Linux中的特殊進程
時間:2023-09-07 來源:未知
1.孤兒進程
父進程退出,子進程不退出,此時子進程被1號(init)進程收養,變成孤兒進程。
孤兒進程會脫離終端控制,且運行在后端,不能用ctrl+c殺死后端進程,但是可以被kill -9殺死
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
//父進程退出 子進程不退出
pid_t cpid = fork();
if(cpid > 0) {
}
else if(0 == cpid) {
while(1) {
printf("this is child %d %d\n", getppid(), getpid()); sleep(1);
}
}
else {
perror("fork"); return -1;
}
return 0;
}
2.僵尸進程
子進程退出,父進程不退出去,且父進程沒有給子進程收尸,此時子進程就變成僵尸進程。
注意:
僵尸進程只能被回收,不能被殺死。
僵尸進程有危害:占用進程號,占用部分內存空間,占用物理空間,占用進程調度塊(PCB)等等...
回收僵尸進程的方式:
退出父進程后,子進程的資源由內核自動回收。
wait / waitpid函數回收。缺點:阻塞函數,父進程無法做自己的事情。非阻塞形式,有可能收不到。
結合信號的方式回收僵尸進程:當子進程退出后,通知父進程收尸。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
//子進程退出,父進程不退出
pid_t cpid = fork();
if(0 == cpid) {
}
else if(cpid > 0) {
while(1)
{
printf("this is parent %d %d\n", getpid(), cpid);
sleep(1);
}
}
else {
perror("fork"); return -1;
}
return 0;
}
3.守護進程
又稱之為幽靈進程。
它們通常在系統引導時啟動,并在沒有用戶交互的情況下運行,用于處理各種系統任務,如發送電子郵件、調度作業、網絡連接等。
守護進程脫離于終端,且運行在后端。
守護進程在執行過程中不會將信息顯示在任何終端上,避免影響前端任務執行。且不會被任何終端產生的終端信息所打斷。
守護進程目的:需要周期性執行某個任務或者周期性等待處理某些事情的時候,為避免影響前端執行或者被前端信息打斷的時候,可以使用守護進程。
守護進程的創建:
創建孤兒進程:所有工作都在子進程中執行,從形式上脫離終端控制。
fork(), 退出父進程
創建新的會話組:使子進程完全獨立出來,防止兄弟進程對其有影響
setsid() 函數
修改當前孤兒進程的運行目錄為不可卸載的文件系統:例如根目錄,/tmp
防止運行目錄被刪除后,導致進程崩潰
chdir函數
注意:從當前位置往后,運行在指定的目錄下;
重設文件權限掩碼:umask(0), 一般清零;
關閉所有文件描述符,從父進程繼承過來的文件描述符不會用到,浪費資源。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
//創建孤兒進程
pid_t cpid = fork();
if(0 == cpid) {
//創建新的會話
pid_t sid = setsid();
//修改運行目錄為不可卸載的文件目錄下
chdir("/");
//清空文件權限掩碼
umask(0);
//關閉所有文件描述符
for(int i = 0; i<getdtablesize(); i++)
close(i);
while(1) {
//守護進程運行的周期性代碼
sleep(1);
}
}
return 0;
}

