日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux进程实践(2) --僵尸进程与文件共享

發布時間:2025/3/17 linux 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux进程实践(2) --僵尸进程与文件共享 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

孤兒進程與僵尸進程

孤兒進程:

? ?如果父進程先退出,子進程還沒退出那么子進程的父進程將變為init進程。(注:任何一個進程都必須有父進程)

//生成孤兒進程 int main(int argc, char *argv[]) {pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0)exit(0);else{sleep(10);cout << "Child, ppid = " << getppid() << endl;}exit(0); }

僵尸進程:

? ?如果子進程先退出,父進程還沒退出,那么子進程必須等到父進程捕獲到了子進程的退出狀態才真正結束,否則這個時候子進程就成為僵尸進程。

//生成僵尸進程 int main(int argc, char *argv[]) {pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0); }

-查詢父子進程狀態

? ps?-le?|?grep?main

?

避免僵尸進程

? ?signal(SIGCHLD,?SIG_IGN);

//示例: 避免僵尸進程 int main(int argc, char *argv[]) {signal(SIGCHLD, SIG_IGN);pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0); }

文件共享

? ?父進程的所有文件描述符都被復制到子進程中,?就好像調用了dup函數,?父進程和子進程每個相同的打開文件描述符共享一個文件表項(因此,?父子進程共享同一個文件偏移量);


//根據上圖: 理解下面這段程序和下圖的演示 int main(int argc, char *argv[]) {signal(SIGCHLD, SIG_IGN);int fd = open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("file open error");cout << "We Don`t flash memory\n";char buf[BUFSIZ];bzero(buf, sizeof(buf));pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0){strcpy(buf, "Parent...");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);}else if (pid == 0){strcpy(buf, "Child...");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);} }

fork?VS?vfork

? 在UNIX/Linux中的fork還沒實現copy?on?write(寫時復制)技術之前。Unix設計者很關心fork之后立刻執行exec所造成的地址空間浪費,所以引入了vfork系統調用。其中,vfork子進程與父進程共享數據段,并不真正復制父進程內存,因此在vfork之后執行exec系列函數,并不會導致地址空間浪費以及無用的空間復制時間.而且,即使fork實現了copy?on?write,效率也沒有vfork高.

? 但是,vfork有個限制,子進程必須立刻執行_exit或者exec系列函數。因此我們不推薦使用vfork,因為幾乎每一個vfork的實現,都或多或少存在一定的問題(可以嘗試在vfork之后的子進程中既不執行_exit,也不執行exec函數)

?

fork與vfork的區別

1. fork子進程拷貝父進程的數據段(但是現在提供了寫時復制技術,只有當子進程真正需要寫內存時,才復制出該內存的一段副本),因此,在父進程/子進程中對全局變量所做的修改并不會影響子進程/父進程的數據內容.

????vfork子進程與父進程共享數據段,因此父子進程對數據的更新是同步的;

2. fork父、子進程的執行次序是未知的,取決于操作系統的調度算法

? ? vfork:子進程先運行,父進程后運行

//示例1:vfork出錯情況 //在Linux 2.6內核上會持續執行,不會退出 //而在Linux 3.13內核上, 則會引發core dump int main() {int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}return 0; }

//示例2: 父進程/子進程修改全局數據的情況 int main() {int iNumber = 10;cout << "Before vfork, pid = " << getpid() << endl;//對比fork()pid_t pid = vfork();if (pid == -1)err_exit("fork");else if (pid > 0){sleep(4);cout << "Parent, iNumber: " << iNumber << endl;}else if (pid == 0){++ iNumber;cout << "Child, iNumber = " << iNumber << endl;_exit(0);}return 0; } //示例3:用vfork執行當前目錄下的hello程序 int main() {int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//將自己寫的程序啟動起來execve("./hello",NULL,NULL);_exit(0);}return 0; }

//測試4,用vfork執行系統命令 int main() {int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//將ls命令啟動起來,注意:由于C++嚴格的類型轉換機制,需要在字符串前加(char*)char *const args[] = {(char *)"/bin/ls", (char *)"-l", NULL};int res = execve("/bin/ls",args,NULL);if (res == -1){perror("execve");_exit(1);}_exit(0);}return 0; }

總結

以上是生活随笔為你收集整理的Linux进程实践(2) --僵尸进程与文件共享的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。