作者:Sunlight丶丶丶 | 来源:互联网 | 2017-10-28 22:45
3. 进程控制与终止
3.1. 进程的控制
一个进程创建子进程后,如果子进程先退出,系统不会自动清理掉子进程的环境,而必须由父进程调用wait或waitpid函数来完成清理工作,如果父进程不做清理工作,则已经退出的子进程将成为僵尸进程(defunct),在系统中如果存在的僵尸进程过多,将会影响系统的性能,所以必须对僵尸进程进行处理。
另一种情况,如果父进程先于子进程退出,则子进程成为孤儿进程,孤儿进程退出后,它的清理工作有祖先进程init自动处理。
函数原型:
#include
#include
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
wait和waitpid都等待一个已经退出的子进程,并进行清理工作;
wait函数随机地等待一个已经退出的子进程,并返回该子进程的pid;
waitpid等待指定pid的子进程;
status参数是传出参数,存放子进程的退出代码;
options的可选项有2个:WNOHANG和WUNTRACED,两参数可用|合成。WNOHANG表示无论子进程是否退出都将立即返回,WUNTRACED极少使用。
示例:
//{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
#include
#include
#include
#include
#include
#include
void SignChildPsExit(int iSignNo)
{
pid_t pid;
int iExitCode;
pid=wait(&iExitCode);
printf("SignNo:%d child %d exit\n",iSignNo,pid);
}
int main()
{
signal(SIGCHLD,SignChildPsExit);
printf("Parent process id:%d\n",getpid());
pid_t iRet=fork();
if(iRet<0){
printf("Create child process fail!\n");
return -1;
}
//}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
3.2. 进程的终止
进程的终止有5种方式:
main函数的自然返回;
调用exit函数
调用_exit函数
调用abort函数
接收到能导致进程终止的信号
前3种方式为正常的终止,后2种为非正常终止。但是无论哪种方式,进程终止时都将执行相同的关闭打开的文件,释放占用的内存等资源。只是后两种终止会导致程序有些代码不会正常的执行,比如对象的析构、atexit函数的执行等。
kill函数
原型为:
#include
#include
int kill(pid_t pid, int sig);
kill函数给进程pid发送信号sig,可发送的信号可以通过shell命令kill -l查看,接收信号的进程如果不对信号进行处理,将会被自动终止。
4. 进程间打开文件的继承
4.1. 用fork继承打开的文件
fork以后的子进程自动继承了父进程的打开的文件,继承以后,父进程关闭调打开的文件不会对子进程造成影响。
示例:
#include
#include
#include
#include
#include
int main()
{
char szBuf[32]={0};
int iFile=open("./a.txt",O_RDONLY);
if(fork()>0){//parent process
close(iFile);
return 0;
}
//child process
sleep(3);//wait for parent process closing fd
if(read(iFile,szBuf,sizeof(szBuf)-1)<1){
perror("read fail");
}else{
printf("string:%s\n",szBuf);
}
close(iFile);
return 0;
}
[1] [2] [3] 下一页