青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

fork, wait, system

Posted on 2009-09-28 13:53 Prayer 閱讀(1238) 評論(0)  編輯 收藏 引用 所屬分類: LINUX/UNIX/AIX

fork,vfork


#include <unistd.h>;
#include <sys/types.h>;

main ()
{
        pid_t pid;
        pid=fork();

        if (pid < 0)
                printf("error in fork!");
        else if (pid == 0)
                printf("i am the child process, my process id is %d\n",getpid());
        else
                printf("i am the parent process, my process id is %d\n",getpid());
}
要搞清楚fork的執行過程,就必須先講清楚操作系統中的“進程(process)”概念。一個進程,主要包含三個元素:

o. 一個可以執行的程序;
o. 和該進程相關聯的全部數據(包括變量,內存空間,緩沖區等等);
o. 程序的執行上下文(execution context)。

不妨簡單理解為,一個進程表示的,就是一個可執行程序的一次執行過程中的一個狀態。操作系統對進程的管理,典型的情況,是通過進程表完成的。進程表中的每 一個表項,記錄的是當前操作系統中一個進程的情況。對于單 CPU的情況而言,每一特定時刻只有一個進程占用 CPU,但是系統中可能同時存在多個活動的(等待執行或繼續執行的)進程。

一個稱為“程序計數器(program counter, pc)”的寄存器,指出當前占用 CPU的進程要執行的下一條指令的位置。

當分給某個進程的 CPU時間已經用完,操作系統將該進程相關的寄存器的值,保存到該進程在進程表中對應的表項里面;把將要接替這個進程占用 CPU的那個進程的上下文,從進程表中讀出,并更新相應的寄存器(這個過程稱為“上下文交換(process context switch)”,實際的上下文交換需要涉及到更多的數據,那和fork無關,不再多說,主要要記住程序寄存器pc指出程序當前已經執行到哪里,是進程上 下文的重要內容,換出 CPU的進程要保存這個寄存器的值,換入CPU的進程,也要根據進程表中保存的本進程執行上下文信息,更新這個寄存器)。

好了,有這些概念打底,可以說fork了。當你的程序執行到下面的語句:
pid=fork();
操作系統創建一個新的進程(子進程),并且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執行程序是同一個程序;上下文和數據,絕大部分就是 原進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執行到fork調用即將返回(此 時子進程不占有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎么返回,在父子進程中就分道揚 鑣。

父進程繼續執行,操作系統對fork的實現,使這個調用在父進程中返回剛剛創建的子進程的pid(一個正整數),所以下面的if語句中pid<0, pid==0的兩個分支都不會執行。所以輸出i am the parent process...

子進程在之后的某個時候得到調度,它的上下文被換入,占據 CPU,操作系統對fork的實現,使得子進程中fork調用返回0。所以在這個進程(注意這不是父進程了哦,雖然是同一個程序,但是這是同一個程序的另 外一次執行,在操作系統中這次執行是由另外一個進程表示的,從執行的角度說和父進程相互獨立)中pid=0。這個進程繼續執行的過程中,if語句中 pid<0不滿足,但是pid==0是true。所以輸出i am the child process...

我想你比較困惑的就是,為什么看上去程序中互斥的兩個分支都被執行了。在一個程序的一次執行中,這當然是不可能的;但是你看到的兩行輸出是來自兩個進程,這兩個進程來自同一個程序的兩次執行。


#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
globa=6;
int main(void)
{
 var=88;
 pid_t result;
 result = fork();
//result = vfork();
 if(result == -1)
 {
  perror("fork");
  exit;
 }
 else if(result == 0)
 {
  globa++;
  var++;
  printf("The return value is %d\n In child process!!\n My PID is %d\n",result,getpid());
 }
 else
 {
  printf("The return value is %d\n In father process!!\n My PID is %d\n",result,getpid());
 }
 printf("PID=%d,globa=%d,var=%d",getpid(),globa,var);
}
程序運行結果如下:
(fork()運行結果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=6,var=88
 
(vfork()運行結果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=7,var=89
 
分析:首先分析fork與vfork函數的運行機制,拿fork為例,fork()并不是進程切換,而是復制一個當前進程。當使用pid= fork()時,其實是創建了兩個進程,這兩個進程有著相同的內容,例如變量的值,空間配,特別是正在執行的語句等等都相同,但這些內容卻在兩個獨立的內 存空間中。因此當執行上述代碼時,便相當于同一段代碼在兩個進程中執行,所有就出現了兩個結果,一個是子進程的信息,一個是父進程的信息。再看globa 和var這兩個變量,由于是兩個獨立的進程,因此當各自執行代碼時,變量也不會互相受到影響,所以在子進程中的globa和var均發生了變化,而在父進 程中卻沒有變化。
     其次分析一下,fork()和vfork()的區別:vfork采用寫時拷貝技術(write-on-copy),父進程與子進程享用同一個內存空間,因 此,程序中的變量其實也就是父子進程的公共變量,所以,當其中一個進程中的變量值發生改變時,另一個進程中的變量值肯定也跟著發生變化,另外,兩個函數的 區別還在于vfork用于創建一個新進程,而該新進程的目的是exec一個新進程,vfork和fork一樣都創建一個子進程,但是它并不將父進程的地址 空間完全復制到子進程中,因為子進程會立即調用exec,于是也就不會存放該地址空間。不過在子進程中調用exec或exit之前,他在父進程的空間中運 行。vfork保證子進程先運行,在她調用exec exit之后父進程才可能被調度運行。如果在調用這兩個函數之前子進程依賴于父進程的進一步動作,則會導致死鎖。 用fork函數創建子進程后,子進程往往要調用一種exec函數以執行另一個程序,當進程調用一種exec函數時,該進程完全由新程序代換,而新程序則從 其main函數開始執行,因為調用exec并不創建新進程,所以前后的進程id 并未改變,exec只是用另一個新程序替換了當前進程的正文,數據,堆和棧段。


wait(等待子進程中斷或結束)
相關函數 waitpid,fork
表頭文件
#include
#include
定義函數 pid_t wait (int * status);
函數說明
wait()會暫時停止目前進程的執行,直到有信號來到或子進程結
束。如果在調用wait()時子進程已經結束,則wait()會立即返
回子進程結束狀態值。子進程的結束狀態值會由參數status 返回,
而子進程的進程識別碼也會一快返回。如果不在意結束狀態值,則
參數status 可以設成NULL。子進程的結束狀態值請參考waitpid()。
返回值
如果執行成功則返回子進程識別碼(PID),如果有錯誤發生則返回
-1。失敗原因存于errno 中。
附加說明
范例
#include
#include
#include
#include
main()
{
pid_t pid;
int status,i;
if(fork()= =0){
printf(“This is the child process .pid =%d\n”,getpid());
exit(5);
}else{
sleep(1);
printf(“This is the parent process ,wait for child...\n”;
pid=wait(&status);
i=WEXITSTATUS(status);
printf(“child’s pid =%d .exit status=^d\n”,pid,i);
}
}
執行
This is the child process.pid=1501
This is the parent process .wait for child...
child’s pid =1501,exit status =5
waitpid(等待子進程中斷或結束)
相關函數 wait,fork
表頭文件
#include
#include
定義函數 pid_t waitpid(pid_t pid,int * status,int options);
函數說明
waitpid()會暫時停止目前進程的執行,直到有信號來到或子進程
結束。如果在調用wait()時子進程已經結束,則wait()會立即
返回子進程結束狀態值。子進程的結束狀態值會由參數status 返回,
而子進程的進程識別碼也會一快返回。如果不在意結束狀態值,則
參數status 可以設成NULL。參數pid 為欲等待的子進程識別碼,
其他數值意義如下:
pid0 等待任何子進程識別碼為pid 的子進程。
參數option 可以為0 或下面的OR 組合:
WNOHANG 如果沒有任何已經結束的子進程則馬上返回,不予以
等待。
WUNTRACED 如果子進程進入暫停執行情況則馬上返回,但結束
狀態不予以理會。
子進程的結束狀態返回后存于status,底下有幾個宏可判別結束情
況:
WIFEXITED(status)如果子進程正常結束則為非0 值。
WEXITSTATUS(status)取得子進程exit()返回的結束代碼,一
般會先用WIFEXITED 來判斷是否正常結束才能使用此宏。
WIFSIGNALED(status)如果子進程是因為信號而結束則此宏值為

WTERMSIG(status) 取得子進程因信號而中止的信號代碼,一般
會先用WIFSIGNALED 來判斷后才使用此宏。
WIFSTOPPED(status) 如果子進程處于暫停執行情況則此宏值為
真。一般只有使用WUNTRACED 時才會有此情況。
WSTOPSIG(status) 取得引發子進程暫停的信號代碼,一般會先
用WIFSTOPPED 來判斷后才使用此宏。
返回值
如果執行成功則返回子進程識別碼(PID),如果有錯誤發生則返回
-1。失敗原因存于errno 中。
范例
參考wait()。

inux的system () 函數詳解
 
 
system(執行shell 命令)
相關函數
        fork,execve,waitpid,popen
表頭文件
        #i nclude<stdlib.h>
定義函數
        int system(const char * string);
函數說明
        system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令,此命>令執行完后隨即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。
返回值
  =-1:出現錯誤  
  =0:調用成功但是沒有出現子進程  
  >0:成功退出的子進程的id
        如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string為空指針(NULL),則返回非零值>。 如果system()調用成功則最后會返回執行shell命令后的返回值,但是此返回值也有可能為 system()調用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。
附加說明
        在編寫具有SUID/SGID權限的程序時請勿使用system(),system()會繼承環境變量,通過環境變量可能會造成系統安全的問題。
范例
        #i nclude<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
執行結果:

-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shado

例2:

char tmp[];
sprintf(tmp,"/bin/mount -t vfat %s /mnt/usb",dev);
system(tmp);
其中dev是/dev/sda1。
 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/alentam/archive/2008/04/09/2270763.aspx

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线观看亚洲视频啊啊啊啊| 亚洲视频欧美视频| 一本一道久久综合狠狠老精东影业| 国产欧美精品一区二区色综合| 国产精品hd| 国产精品国色综合久久| 国产亚洲精品v| 一区二区视频欧美| 亚洲欧洲一区二区在线播放| 99视频在线观看一区三区| 中国亚洲黄色| 久久激情五月丁香伊人| 免费观看30秒视频久久| 欧美日韩精品在线观看| 欧美另类综合| 国产亚洲欧美在线| 亚洲美女诱惑| 久久久久久夜精品精品免费| 久久精品综合网| 欧美激情视频给我| 一本色道久久综合亚洲精品高清 | 日韩视频在线免费观看| 一区二区三区|亚洲午夜| 亚洲欧美国产日韩天堂区| 久久免费一区| 亚洲视频综合在线| 欧美不卡在线视频| 国产情人节一区| 日韩视频免费观看高清完整版| 一区二区三区欧美亚洲| 久久一区中文字幕| 亚洲性感激情| 欧美日韩精选| 亚洲国产视频直播| 久久九九电影| 亚洲视频中文字幕| 欧美日本精品一区二区三区| 国产主播在线一区| 亚洲女人小视频在线观看| 国产精品啊v在线| 亚洲国产老妈| 久久综合999| 亚洲欧美日韩一区在线| 欧美日韩亚洲高清| 亚洲精品一区二区三区av| 久久五月婷婷丁香社区| 亚洲特级毛片| 欧美天天在线| 亚洲午夜一区二区| 亚洲人屁股眼子交8| 91久久精品美女| 老司机精品久久| 国内精品久久久久伊人av| 亚洲免费视频成人| 一区二区精品国产| 欧美日韩日本视频| 99国产精品99久久久久久粉嫩| 欧美激情久久久久久| 性刺激综合网| 国产农村妇女毛片精品久久莱园子| 亚洲国产视频一区二区| 欧美黑人在线观看| 欧美激情第三页| 一区二区三区导航| 亚洲图色在线| 国产主播喷水一区二区| 久热re这里精品视频在线6| 欧美一区二区三区喷汁尤物| 国产欧美日韩综合一区在线观看 | 国产午夜精品一区二区三区欧美| 亚洲欧美日韩天堂一区二区| 亚洲天堂久久| 国产精品你懂得| 先锋a资源在线看亚洲| 国产精品揄拍500视频| 欧美一级久久久| 欧美一区二区三区久久精品茉莉花| 国产偷国产偷精品高清尤物| 久久久国产一区二区| 久久精品国产第一区二区三区| 在线播放不卡| 亚洲精选一区二区| 国产视频观看一区| 亚洲国产二区| 国产精品黄色| 另类av导航| 欧美日韩国产经典色站一区二区三区| 亚洲视频香蕉人妖| 欧美一区二区三区男人的天堂| 最新中文字幕亚洲| 一本在线高清不卡dvd| 黑人一区二区三区四区五区| 亚洲成人资源| 国产欧美在线播放| 欧美激情亚洲国产| 国产精品另类一区| 欧美h视频在线| 欧美午夜视频在线| 免费av成人在线| 欧美特黄a级高清免费大片a级| 久久天天狠狠| 国产精品大片wwwwww| 欧美国产精品人人做人人爱| 欧美性一二三区| 欧美激情一区二区三区四区| 国产精品免费区二区三区观看| 欧美成人一区在线| 国产欧美一二三区| 亚洲麻豆av| 亚洲国产老妈| 欧美在线视频观看| 亚洲自拍三区| 欧美日韩国产首页在线观看| 免费久久99精品国产自在现线| 国产精品少妇自拍| 一本综合精品| 亚洲欧美日本国产有色| 欧美精品在线一区二区三区| 久久一区二区三区四区五区| 国产精品乱码一区二三区小蝌蚪| 亚洲国产精品成人综合色在线婷婷| 国产精品一区二区a| 99在线|亚洲一区二区| 亚洲麻豆一区| 欧美激情网友自拍| 亚洲国产精品女人久久久| 国内精品久久久久久影视8| 亚洲欧美日韩国产| 欧美在线视频不卡| 国产欧美一区二区三区在线看蜜臀| 日韩一级不卡| 亚洲午夜久久久久久久久电影网| 欧美精品三级| 亚洲精品国产精品国自产观看浪潮| 黄色亚洲在线| 久久男人资源视频| 老司机精品导航| 亚洲国产老妈| 欧美日韩不卡一区| 欧美成人蜜桃| 亚洲激情啪啪| 日韩视频一区二区在线观看| 久久综合伊人77777尤物| 欧美成年视频| 亚洲伦理中文字幕| 欧美日韩成人在线播放| 亚洲免费观看| 欧美一级理论性理论a| 国产久一道中文一区| 欧美影院精品一区| 免费日韩视频| 999亚洲国产精| 欧美午夜宅男影院| 午夜精品视频在线| 蜜臀av一级做a爰片久久| 999亚洲国产精| 国产精品免费一区二区三区在线观看 | 欧美伦理91i| 一区二区三区精品久久久| 欧美一区二区三区免费在线看| 国产日韩精品久久| 久久久在线视频| 91久久国产综合久久| 亚洲综合色视频| 国产在线不卡| 欧美高清视频www夜色资源网| 亚洲精品中文字幕女同| 欧美一区二区三区视频免费播放| 狠狠综合久久| 欧美日韩视频在线一区二区| 亚洲一区二区三区在线观看视频| 久久久噜久噜久久综合| 亚洲区中文字幕| 国产欧美另类| 欧美日韩国产精品一区二区亚洲 | 欧美三级不卡| 欧美亚洲一区在线| 亚洲精品中文字幕在线观看| 久久久久久噜噜噜久久久精品| 亚洲精品欧美日韩专区| 国产欧美日韩三区| 欧美日韩三区四区| 免费欧美在线| 久久久久久九九九九| 日韩视频免费在线| 欧美成年人视频网站| 久久国产色av| 午夜宅男欧美| 亚洲小说春色综合另类电影| 亚洲激情自拍| 国产一区激情| 国产精品久久久久91| 欧美r片在线| 久久久xxx| 欧美一区二区视频97| 一本一道久久综合狠狠老精东影业 | 国产精品久久久久999| 男同欧美伦乱| 久久久久一区二区三区| 好吊视频一区二区三区四区|