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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

启动进程 问号_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇

發布時間:2025/4/5 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 启动进程 问号_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

進程

先來說下什么是進程:

來看下百度是怎么說的:

光看說的不夠形象,在windows系統中,它長這樣:

在Mac系統中,它長這樣:

Linux中是這樣的:(有點長截圖一部分好了)

[root@iz2ze76ybn73dvwmdij06zz ~]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 5月20 ? 00:00:33 /usr/lib/systemd/systemd --system --deserialize 21 root 2 0 0 5月20 ? 00:00:00 [kthreadd] root 3 2 0 5月20 ? 00:00:06 [ksoftirqd/0] root 5 2 0 5月20 ? 00:00:00 [kworker/0:0H] root 7 2 0 5月20 ? 00:00:02 [migration/0] root 8 2 0 5月20 ? 00:00:00 [rcu_bh] root 9 2 0 5月20 ? 00:30:40 [rcu_sched] root 10 2 0 5月20 ? 00:00:17 [watchdog/0] root 11 2 0 5月20 ? 00:00:16 [watchdog/1] root 12 2 0 5月20 ? 00:00:02 [migration/1] root 13 2 0 5月20 ? 00:00:03 [ksoftirqd/1] root 15 2 0 5月20 ? 00:00:00 [kworker/1:0H] root 17 2 0 5月20 ? 00:00:00 [kdevtmpfs] root 18 2 0 5月20 ? 00:00:00 [netns] root 19 2 0 5月20 ? 00:00:01 [khungtaskd] root 20 2 0 5月20 ? 00:00:00 [writeback] root 21 2 0 5月20 ? 00:00:00 [kintegrityd] root 22 2 0 5月20 ? 00:00:00 [bioset] root 23 2 0 5月20 ? 00:00:00 [kblockd] 復制代碼

OK,以上每一行都是對一個進程的描述,來具體看一下每個參數的含義:

標示 描述 UID 用戶ID PID 進程ID PPID 父進程ID C 進程占cpu百分比 STIME 進程啟動的時間 TTY 終端機位置 TIME 實際使用cpu的時間 CMD 命令以及參數

我們現在知道了每個參數的含義,既然講到進程嘛,首先,進程ID是唯一的并且是非負數的,但是進程ID是可以復用的,畢竟進程也會終止。

可以看到沒有進程PID是0的,這是為什么呢? 黑人問號臉?

0一般來說是系統進程,屬于內核的一部分,不執行任何磁盤上的程序。

fork

一個進程可以通過調用fork函數創建新的進程,被創建出來的這個進程就叫子進程。

這里需要注意一下,fork函數的返回值父子進程區別。

  • 子進程 : 返回值是0,返回0的理由是子進程的父進程是可以唯一確定的,通過getppid方法可以獲取到父進程id。
  • 父進程 : 返回的是新創建的子進程的id,因為父進程可以有多個子進程,也沒有這樣的函數可以獲取該線程的子線程的所有id。

下邊的話我們來驗證一下上說的這一段話。準備好腳本。

#include <sys/types.h> #include <unistd.h> #include <stdio.h>int main(int argc, char const *argv[]) {pid_t p1 = fork();printf("%dn",p1);if(p1 > 0){printf("父進程 pid = %d, p1 = %dn", getpid(), p1);}else{printf("子進程 pid = %d , ppid = %d, p1 = %dn", getpid(), getppid(), p1);}return 0; } 復制代碼

運行看結果:

[root@iz2ze76ybn73dvwmdij06zz ~]# ./fork2 10213 父進程 pid = 10212, p1 = 10213 0 子進程 pid = 10213 , ppid = 10212, p1 = 0 復制代碼

通過上面的小例子我們可以看到父進程的返回值是子進程的ID,子進程的返回是0。

孤兒進程

孤兒我們都懂就是。。。

是的,沒錯孤兒進程也是這樣的,就是沒有父進程的進程。當然創建的時候肯定是要先創建父進程了,當父進程退出時,它的子進程們(一個或者多個)就成了孤兒進程了。

接下來在繼續做一個小測試,讓父進程現退出。準備好腳本。

[root@iz2ze76ybn73dvwmdij06zz ~]# cat guer.c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork error;");exit(1);} else if (pid == 0) {sleep(5);printf ("子進程 : [ pid] = %d , 父進程 [ppid] = %dn",getpid(),getppid());exit(0);} else if (pid > 0) {printf("我是父線程,我先退出一步~n");exit(0);}return 0; } 復制代碼

執行并看結果:

到這里估計很多童鞋估計已經看懂了,父進程退出后,子進程被一個進程ID為1的進程領養的。還挺好這個結果,至少還是有人管的,被暖到了~ 進程id為1的進程是init進程,每當有孤兒進程出現時,init進程就會收養它并成為它的父進程 ,來照顧它以孤兒進程以后的生活。

危害

因為孤兒進程會被init進程接管,所以孤兒進程是沒有危害的。

僵尸進程

和孤兒進程相反的是,這次是子進程先退出,而父進程又沒有去處理回收釋放子進程的資源,這個時候子進程就成了僵尸進程。

先準備好代碼:

[root@iz2ze76ybn73dvwmdij06zz ~]# cat zombie.c#include <stdio.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>int main(){pid_t pid;pid = fork();if (pid < 0){perror("fork error:");exit(1);}else if (pid == 0){printf("我是子進程,我要先退出一步了.n");printf("子進程 id : %dn" ,getpid());exit(0);} else {printf("我是父進程,我先睡2秒n");printf("父進程 id : %dn" ,getpid());sleep(2);while(2); //來個死循環,不退出的那種}return 0;} 復制代碼

運行看下結果:

再來開一個終端看下進程結果:

大家可以看到,子進程并沒有完全退出,釋放資源,而是變成了僵尸進程。

危害

資源上是占用不了什么資源。但是通常系統的進程數量都是有限制的,如果有大量的僵尸進程占用進程號,導致新的進程無法創建,這個危害類似于占個坑,不辦事,別人也辦不了事。

處理

1.干掉父進程

干掉父進程后,讓剩下的子進程成為孤兒進程,成為孤兒進程后就和我們上面說的一樣了,由init進程來領養這些進程,并且來處理這些進程的資源釋放等工作。

2.父進程調用wait或waitpid

等函數等待子進程結束,這會導致父進程掛起。 執行wait()或 waitpid()系統調用,則子進程在終止后會立即把它在進程表中的數據返回給父進程,此時系統會立即刪除該進入點。在這種情形下就不會產生defunct進程。

3.fork兩次

第一次 fork : 父進程fork一個子進程

第二次 fork : 子進程fork一個孫進程后退出

那么孫進程被init接管,當孫進程結束后,init會回收。

但子進程的回收還要自己做。

4.signal函數

父進程來處理:用signal函數為SIGCHLD安裝handler,在子進程結束后,父進程會收到該信號,可以在handler中調用wait回收。

內核來處理: 如果父進程不關心子進程什么時候結束,可以通過以下兩個函數通知內核自己不感興趣子進程的結束,此時,子進程結束后,內核會回收并不再給你父進程發信號。

  • signal(SIGCLD, SIG_IGN)
  • signal(SIGCHLD, SIG_IGN)

總結

本來以為簡單的一個問題,沒想到這個篇幅其實也不算短,所以感覺程序員真的不能說一個什么知識點就簡單,很容易理解啊,一旦你想要深入也是需要一定的時間花費和精力的~

總結

以上是生活随笔為你收集整理的启动进程 问号_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇的全部內容,希望文章能夠幫你解決所遇到的問題。

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