殭屍程式,孤兒程式,wait,exit,execl等函式使用要點
程式號為1的程式是所有程式的主先程式init
如何檢視程式:ps uax
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int a = 8;
printf("current process id:%d\n",getpid());
pid = fork();
if( pid > 0 )//父程式所做之事
{
printf("a = %d\n",a);
printf(" pid = %d\n",pid);//子程式
printf(" ppid = %d\n",getpid());//父程式
//while(1);
}else if( pid == 0 )//子程式所做之萬
{
a++;
printf("aa = %d\n",a);
printf("child pid = %d\n",getpid());//子程式
printf("parent pid = %d\n",getppid());//父程式
//while(1);
}else{
printf("fork error!\n");
}
exit(0);
}
/*
* fork函式:
* 1.fork函式用於建立子程式。子程式
* 繼承父程式之前執行的一切狀態,並
* 且拷貝父程式的地址空間,成為父
* 程式的一個副本。子程式從fork函式
* 的下一句話開始執行。
* 2.fork函式不能保證父程式和子程式
* 哪個先執行。
* 這裡相當於兩個程式在執行,所以出現的結果是六個
*/
結果:
current process id:1995
a = 8
pid = 1996
ppid = 1995
aa = 9
child pid = 1996
parent pid = 1995
殭屍程式的產生:
/*
============================================================================
Name : jianshiprocess.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
//長生殭屍程式
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<sys/types.h>
//殭屍程式:
//子程式在父程式前退出,此時子程式成為殭屍程式。
//孤兒程式:
//父程式在子程式之前退出,此時子程式成為孤兒程式,此子程式由init程式零養,(也就是說init程式成為子程式的父程式,init程式是所有孤兒程式的父程式)
//著兩種都是要避免的
int main(void)
{
pid_t pid;
pid=fork();
if(pid>0)
{
sleep(10);//讓父程式等在這裡,之後被喚醒
}
else if(pid==0)
{
printf("child%d",getpid());
printf("p%d",getppid());
exit(0);//成為殭屍程式後,佔用程式好
}
else
{
puts("wrong");
exit(0);
}
return EXIT_SUCCESS;
}
孤兒程式:
/*
============================================================================
Name : guerprocess.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<sys/types.h>
int main(void) {
int i;
pid_t pid;
printf("current process id:%d\n",getpid());
pid=fork();
if(pid>0)
{
exit(0);//成為殭屍程式後,佔用程式好
}
else if(pid==0)
{
for(i=0;i<20;i++)
{
printf("child:%d\n",getpid());
printf("parent:%d\n",getppid());
}
}
else
{
puts("wrong");
exit(0);
}
return EXIT_SUCCESS;
}
奇怪的現象:如果在這個程式的執行過程中,按ctrl+c阻止程式的進行,會發現阻止不了,因為此時的子程式成了孤兒程式,成了主程式的守護程式,因為它的父程式是init程式,而ctrl+c只能阻止前臺執行的程式
2:
return 與exit的區別:
return 用於函式返回,只有main函式呼叫時,程式才退出
而exit函式被呼叫,此程式直接退出
exit與_exit的相同點:
都是用於程式退出。
不同點:
exit函式在程式退出之前,會重新整理檔案緩衝區到檔案中。
_exit在程式退出之前,不會重新整理緩衝區,也就說直接丟棄緩衝區裡面的內容
fork與vfork
執行fork建立子程式時,子程式將拷貝父程式的資料段、堆段和棧段,此時父子程式的資料一致當互相獨立,各不影響,子程式對資料的處理不影響父程式。(其實當父子程式都不對三個段進行寫操作時,父子程式仍然共享資料段、堆段和棧段,當有任何一方有寫操作時,才產生副本,這種方式成為寫是複製)
vfork與fork區別有兩點:1、vfork建立的子程式與父程式共享資料段,2、vfork建立的子程式優先於父程式執行,當子程式執行時,父程式進入阻塞狀態。
所以vfork產生的子程式對資料的修改一定可以影響到父程式的資料
exit與_exit
exit:當執行exit時,終止處理程式,執行標準的I/O清楚操作(將快取中檔案寫入),呼叫atexit,呼叫_exit。由此可見,exit是加強版的_exit.
_exit:通知核心,程式結束
程式碼區別:printf("hello");
exit(0);//
結果:輸出hello,重新整理緩衝區
printf("hello");
_exit(0)
結果,不輸出,直接丟棄緩衝區裡面的內容
3.wait函式:
wait(等待子程式中斷或結束) | |
相關函式
|
waitpid,fork |
表標頭檔案
|
#include<sys/types.h> #include<sys/wait.h> |
定義函式
|
pid_t wait (int * status); |
函式說明
|
wait()會暫時停止目前程式的執行,直到有訊號來到或子程式結束。如果在呼叫wait()時子程式已經結束,則wait()會立即返回子程式結束狀態值。子程式的結束狀態值會由引數status 返回,而子程式的程式識別碼也會一快返回。如果不在意結束狀態值,則 |
引數
|
status可以設成NULL。子程式的結束狀態值請參考waitpid()。 |
返回值
|
如果執行成功則返回子程式識別碼(PID),如果有錯誤發生則返回-1。失敗原因存於errno中。 |
1.呼叫到wait函式的程式直接阻塞
2.一般由父程式呼叫,用於回收子程式退出時,其所佔有的資源,避免其成為殭屍程式
3.如果一個程式呼叫到此函式,且其沒有子程式,wait函式直接返回
4.處理SIGCHL訊號(當子程式狀態改變時,核心會向其父程式傳送SIGCHL訊號,使用者程式對於此訊號的預設處理方式為忽略)
5.呼叫到wait函式程式的任何一個子程式退出,此函式返回。(或者搜到SIGCHL函式則也退出)
6.獲取子程式的狀態值wait(&status)
如:exit(7),7是整形常量,佔32位,取整形常量的低八位,放在status的32位的高八位,如果把status裡面的值右移八位,就又變成7(status是個整形變數),因為它的低八位要被其它訊號量佔用.(exit裡面的值只能是0-255)
一個wait只能回收一個子程式的空間
7.無法確定回收某個指定的子程式
j程式一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程式的某個子程式已經退出,如果讓它找到了這樣一個已經變成殭屍的子程式,wait就會收集這個子程式的資訊,並把它徹底銷燬後返回;如果沒有找到這樣一個子程式,wait就會一直阻塞在這裡,直到有一個出現為止。
引數status用來儲存被收集程式退出時的一些狀態,它是一個指向int型別的指標。但如果我們對這個子程式是如何死掉的毫不在意,只想把這個殭屍程式消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個引數為NULL,就象下面這樣
- pid = wait(NULL);
如果成功,wait會返回被收集的子程式的程式ID,如果呼叫程式沒有子程式,呼叫就會失敗,此時wait返回-1,同時errno被置為ECHILD。
如果引數status的值不是NULL,wait就會把子程式退出時的狀態取出並存入其中,這是一個整數值(int),指出了子程式是正常退出還是被非正常結束的(一個程式也可以被其他程式用訊號結束,我們將在以後的文章中介紹),以及正常結束時的返回值,或被哪一個訊號結束的等資訊。由於這些資訊被存放在一個整數的不同二進位制位中,所以用常規的方法讀取會非常麻煩,人們就設計了一套專門的巨集(macro)來完成這項工作,下面我們來學習一下其中最常用的兩個:
1,WIFEXITED(status)這個巨集用來指出子程式是否為正常退出的,如果是,它會返回一個非零值。
(請注意,雖然名字一樣,這裡的引數status並不同於wait唯一的引數--指向整數的指標status,而是那個指標所指向的整數,切記不要搞混了。)
2, WEXITSTATUS(status)當WIFEXITED返回非零值時,我們可以用這個巨集來提取子程式的返回值,如果子程式呼叫exit(5)退出,WEXITSTATUS(status)就會返回5;如果子程式呼叫exit(7),WEXITSTATUS(status)就會返回7。請注意,如果程式不是正常退出的,也就是說,WIFEXITED返回0,這個值就毫無意義。
/*============================================================================
Name : wait.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
//多用於父程式和多程式中
#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main(void) {
pid_t pid;
int status;
pid=fork();
if(pid>0)
{
wait(&status);
printf("this is a parent process\n");
if(WIFEXITED(status))
{
printf("status is %d \n",WEXITSTATUS(status));
}
exit(0);
}
else if(pid==0)
{
printf("this is a child process!\n");
exit(7);
}
else
{
printf("fork error!\n");
exit(1);
}
return EXIT_SUCCESS;
}
4.wait_pid
|
waitpid(等待子程式中斷或結束) |
相關函式
|
wait,fork |
表標頭檔案
|
#include<sys/types.h> #include<sys/wait.h> |
定義函式
|
pid_t waitpid(pid_t pid,int * status,int options); |
函式說明
|
waitpid()會暫時停止目前程式的執行,直到有訊號來到或子程式結束。如果在呼叫wait()時子程式已經結束,則wait()會立即返回子程式結束狀態值。子程式的結束狀態值會由引數status返回,而子程式的程式識別碼也會一快返回。如果不在意結束狀態值,則引數status可以設成NULL。引數pid為欲等待的子程式識別碼,其他數值意義如下: pid<-1 等待程式組識別碼為pid絕對值的任何子程式。 pid=-1 等待任何子程式,相當於wait()。 pid=0 等待程式組識別碼與目前程式相同的任何子程式。 pid>0 等待任何子程式識別碼為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 來判斷後才使用此巨集。 |
execl:
|
execl(執行檔案)
main()
{
execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )0);
}
-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd 執行之後的語句很有可能被擦除掉,而之前的還在
相關文章
- 殭屍程式,孤兒程式
- 殭屍程式和孤兒程式
- Perl程式:殭屍程式和孤兒程式
- 子程式、孤兒程式,殭屍程式, init程式
- Go Exec 殭屍與孤兒程式Go
- UNIXC002 程式資源的回收、孤兒程式和殭屍程式
- 孤兒程序和殭屍程序
- PHP 多程式之孤兒和殭屍簡單講解PHP
- 從一道面試題來學習前臺程式和後臺程式、孤兒程式和殭屍程式面試題
- 聊聊 PHP 多程序模式下的孤兒程序和殭屍程序PHP模式
- 程序物件、殭屍程序與孤兒程序、守護程序、互斥鎖物件
- fork和殭屍程式
- Linux中殭屍程式是什麼意思?怎麼檢視殭屍程式?Linux
- 檢視 Linux 殭屍程式Linux
- Linux殭屍程式處置Linux
- 阻塞程式函式 wait()和waitpid()函式AI
- Linux 中殭屍程式詳解Linux
- Linux系統殭屍程式詳解Linux
- Linux系統程式設計——特殊程式之孤兒程式Linux程式設計
- JaCoCo助您毀滅線上殭屍程式碼
- Linux 效能優化之 CPU 篇 ----- 殭屍程式Linux優化
- 什麼是殭屍程式以及如何處理
- 物聯網教程Linux系統程式設計——特殊程式之殭屍程式Linux程式設計
- 孤兒程式與終端的關係
- quit(code=None)函式和exit(code=None)函式的使用舉例UINone函式
- C程式起點main函式C程式AI函式
- 這就是你們要的《植物大戰殭屍3》
- CodeMonkey少兒程式設計第7章 函式程式設計函式
- 系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?
- 案例:系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?
- 盤點:網際網路上無處不在的"殭屍"
- 植物大戰殭屍,用QT注入程式碼,AT&T彙編語法QT
- mysql MASTER_POS_WAIT函式MySqlASTAI函式
- Unity 植物大戰殭屍(一)Unity
- 什麼是殭屍網路
- Python 植物大戰殭屍程式碼實現(2):植物卡片選擇和種植Python
- 使用chatgt(GPT-4)將過程式(的java程式碼)改成函式式(的elixir程式碼)GPTJava函式
- 3.19實戰殭屍工廠1
- 3.20實戰殭屍工廠2