return() 與exit() 的區別

在初學編程的過程中,往往return和exit我們不做過多的區分,都只認爲是程序的結束,例如我們寫的第一個程序

#include <iostream>
int main()
{
    using namespace std;
    cout << "Helloword!";
    cin.get();
    //exit(0);
    return 0;
}

無論使用exit()或是使用return都能結束程序的那麼區別在哪裏?
區別在於return會調用所有靜態變量的析構函數,完成退棧;
而exit()不會。

那麼這好像沒什麼所謂吧,程序都結束了好像沒什麼所謂吧。退就退了,留着搞什麼啊,那麼我們先來回憶一下兩個常用的東西fork和vfork。

複習下進程吧
進程由4個要素組成:
①進程控制塊:進程標誌
②進程程序塊:可與其他進程共享
③進程數據塊:進程的私有空間,用於存放私有的數據及堆棧空間
④獨立的空間:進程必須有的條件

fork()創建子進程,複製了父進程的資源,包括內存內容、task_struct內容,新舊進程使用同一段代碼,複製數據段和堆棧段,一但子進程開始運行,則新的進程的地址已經分開,兩者運行獨立.

vfork()創建的子進程完全運行在父進程的地址空間上
子進程對虛擬地址空間任何數據的修改父進程可見!!!
子進程對虛擬地址空間任何數據的修改父進程可見!!!
子進程對虛擬地址空間任何數據的修改父進程可見!!!
父進程會被子進程阻塞,子進程結束。

先來看一段代碼吧

 #include <iostream>
#include <stdlib.h> 
#include <unistd.h>
int glob = 6;
int main()
{
    using namespace std;
    int var;  

    pid_t pid;  
    var = 88;
    cout<<"before vforkn"<<endl;
    if ((pid = vfork()) < 0)
    {
        cout<<"vfork error"<<endl;
        exit(-1);
    }
    else if (pid == 0)
    {
        /* 子進程 */
        glob++;
        var++;
        return 0;
        //exit(0);    
    }
    cout << getpid() << "  " << glob << "  " << var << "  " << endl;
    return 0;
    //exit(0); 
}

這裏稍微解釋一下fork和vfork是兩個很有趣的函數,他反發返回值會有3種情況:
①在父進程中,fork(vfork)返回新創建的子進程的進程ID;
②在子進程中,fork(vfork)返回0,可以用來判斷是不是子進程;
③如果出錯,fork(vfork)返回一個負值。

好了說這裏,我們可以猜測一下輸出應該是什麼
應該是
進程識別碼 7 89
那麼實際的輸出結果是什麼吶?
這裏寫圖片描述
這是什麼鬼,爲什麼最後那個數不是89吶?
我們先把它改成exit(0)試試看
這裏寫圖片描述
正常了,這是爲什麼吶?
回到我們一開始說的return和exit的區別上
return 會退棧,會釋放靜態變量,由於vfork使用的是父進程的空間,當子進程return的時候
int var;
var = 88;
作爲動態存儲的數據,存儲在棧上,由於退棧,會被釋放;
當子進程結束後
父進程該打印var的值的時候會怎麼辦,var已經被兒子釋放了,這不是坑爹嗎?
glob=7不受影響是因爲它作爲靜態存儲的變量,不會受到退棧的影響。
將var改爲static int;後結果var的值會變回89但是還是存在問題,大家可以繼續研究研究。

發佈了44 篇原創文章 · 獲贊 25 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章