Linux进程模型2

1、execve函数

在父进程中fork一个子进程,在子进程中调用execve函数启动新的程序,代替

原有进程,被执行进程的PID不会改变。例子代码如下:

int main(int arg, char *args[])

{
close(STDOUT_FILENO);//关闭标准输出
open("/dev/pts/1", O_WRONLY);//打开"/dev/pts/1",做为标准输出
pid_t pid = fork();//调用fork产生一个子进程
int status;
if (pid == -1)
{
printf("fork failed\n");
return 0;
}
if (pid == 0)//子进程调用execve,执行ls -l命令
{
char *args[] = { "/bin/ls", "-l", NULL };
execve("/bin/ls", args, NULL);
}
else
{
return 0;//父进程退出
}
}

2、僵死进程

父进程没有调用wait,子进程就退出了,这个时候子进程就成了僵死进程。


//此例子是父进程等待子进程退出的代码
int main(int arg, char *args[])
{
pid_t pid = fork();//调用fork之后会有两个进程
int status;
if (pid == 0)
{
printf("child begin\n");
sleep(5);
printf("child end\n");
return -1;
}
if (pid > 0)
{
printf("parent begin\n");
wait(&status);//阻塞调用,直到子进程退出,wait才返回
printf("child return = %d\n", WEXITSTATUS(status));
printf("parent end\n");
}
return 0;

}

3、孤儿进程

父进程在调用wait或者waitpid之前就已经退出的子进程。此时init进程成为子进程的父进程。

如:

int main(int arg, char *args[])
{
pid_t pid = 0;
pid = fork();
if (pid == 0)
{
while(1)

{

printf("child\n");

sleep(1);

printf("ppid = %d\n", getppid());

}
}
if (pid > 0)
{
exit(0);
}
return 0;

}

4、结束进程

一个进程由以下5个原因中的一个终止。

1)main函数调用了return;

2)调用了exit;

3)调用了_exit;

4)调用了abort函数;

5)被一个信号终止。

前三个是正常终止,后两个是非正常终止。无论进程如何终止,最后都执行相同的内核代码,关闭打开的文件,释放内存资源和其他清理工作。

return和exit的区别:

在主函数中一样,在子函数中,return只是子函数退出到主函数,退出码只能从主函数得到;若想在子函数中也得到退出码,则用exit。

abort函数:

当碰到一个很严重内存不足这样的错误,无法用程序的方式处理时再使用abort。

kill函数:

用kill函数杀死一个进程,杀死进程用SIGKILL信号,例子如下:

int main(int arg, char *args[])
{
if(arg > 1)
{
int pid = atoi(args[1]);
kill(pid,SIGKILL);
}else
{
printf("pid = %u\n", getpid());
sleep(100);
}
return EXIT_SUCCESS;
}



猜你喜欢

转载自blog.csdn.net/zangyongcan/article/details/51946009
今日推荐