linux进程退出控制
在Linux系统中,当进程退出时,必须释放它所拥有的资源,并通过某种方式告诉父进程。进程的退出一般是显示或隐式地调用了eixt(),或者接受了某种信号。不管是由于什么原因退出,最终都调用了do_exit。进程退出的种类Linux下进程的退出分为正常退出和异常退出两种。正常退出a. 在main()函数中执行return;b.调用exit()函数。异常退出a.调...
在Linux系统中,当进程退出时,必须释放它所拥有的资源,并通过某种方式告诉父进程。进程的退出一般是显示或隐式地调用了eixt()
,或者接受了某种信号。不管是由于什么原因退出,最终都调用了do_exit
。
进程退出的种类
Linux下进程的退出分为正常退出和异常退出两种。
-
正常退出
a. 在main()
函数中执行return
;
b.调用exit()
函数。 -
异常退出
a.调用abort
函数;
b.进程收到某个信号,而该信号使程序终止。
不管是哪种退出方式,系统最终都会执行内核中的同一代码。这段代码用来关闭进程用到的文件描述符,释放它所占用的内存和其他资源。
父子进程退出的顺序
-
父进程先于子进程终止:
此种情况下,父进程会变成孤儿进程。当父进程先退出时,系统会让init进程接管子进程。 -
子进程先于父进程终止,而父进程又没有调用
wait
函数
此种情况子进程进入僵死状态,并且会一直保持下去直到系统重启。子进程处于僵死状态时,内核只保存进程的一些必要信息以备父进程所需。此时子进程始终占有着资源,同时也减少了系统可以创建的最大进程数。 -
子进程先于父进程终止,而父进程调用了wait函数
此时父进程会等待子进程结束。
实例
任务描述
试想这样的场景:
你的朋友和你一起到逛超市,逛的途中你们分散了,你们各自走出超市出口的先后顺序不同有三种情况。
整个过程如下:
- 你的朋友先出去;
- 你先出去,你没有等你的朋友;
- 你先出去,你在出口等你的朋友。
以进程退出的三种可能性代替这三种情况:
- 父进程先退出;
- 子进程先退出,父进程没有调用等待函数;
- 子进程先退出,父进程调用了等待函数。
在主函数的最开始会初始化一个全部变量g_i4event
为0
。
本关的编程任务是补全右侧代码片段中三段Begin
至End
中间的代码,具体要求如下:
-
father_son中,创建子进程后,将
g_i4event
置为1
;父进程睡眠一秒后将g_i4event
置为2
,接着直接退出;子进程睡眠两秒后直接退出; -
son_father_nowait中,创建子进程后,将
g_i4event
置为1
;子进程睡眠一秒后直接退出;父进程睡眠两秒后将g_i4event
置为3
直接退出; -
son_father_wait中,创建子进程后,将
g_i4event
置为1
;子进程睡眠一秒后直接退出;父进程等待子进程退出,然后睡眠一秒,随后将g_i4event
置为4
退出。
测试样例:
测试输入:1
预期输出:You and your friend go to the supermarket!
Your friend go out first!
测试输入:2
预期输出:You and your friend go to the supermarket!
You go out first!You will not wait for your friend!
测试输入:3
预期输出:You and your friend go to the supermarket!
You go out first! You will wait for your friend!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include<sys/wait.h>
pthread_t pid;
int g_i4event = 0;
int father_son(void);
int son_father_nowait(void);
int son_father_wait(void);
int father_son(void)
{
/********Begin********/
int rc=fork();
g_i4event=1;
if(rc==0)
sleep(2);
else
{
sleep(1);
g_i4event=2;
}
return 0;
/*********End*********/
}
int son_father_nowait(void)
{
/********Begin********/
int rc=fork();
g_i4event=1;
if(rc==0)
{
sleep(1);
}
else
{
sleep(2);
g_i4event=3;
}
return 0;
/*********End*********/
}
int son_father_wait(void)
{
/********Begin********/
int rc=fork();
g_i4event=1;
if(rc==0)
{
sleep(1);
}
else
{
wait(NULL);
sleep(1);
g_i4event=4;
}
return 0;
/*********End*********/
}
void *detect(void *arg)
{
int count = 0;
while (1)
{
switch(g_i4event)
{
case 0:
break;
case 1:
count ++;
printf("You and your friend go to the supermarket!\n");
break;
case 2:
count ++;
if(2 == count)
{
printf("Your friend go out first!\n");
}
return NULL;
case 3:
count ++;
if(2 == count)
{
printf("You go out first!You will not wait for your friend!\n");
}
return NULL;
case 4:
count ++;
if(2 == count)
{
printf("You go out first! You will wait for your friend!\n");
}
return NULL;
default:
break;
}
g_i4event = 0;
usleep(10 * 1000);
}
return NULL;
}
#define FATHER_SON 1
#define SON_FATHER_NOWAIT 2
#define SON_FATHER_WAIT 3
int main(int argc, char *argv[])
{
char cmd[32] = {0};
scanf("%s", cmd);
pthread_create(&pid, NULL, detect, NULL);
if(FATHER_SON == atoi(cmd))
{
father_son ();
}
else if(SON_FATHER_NOWAIT == atoi(cmd))
{
son_father_nowait ();
}
else if(SON_FATHER_WAIT == atoi(cmd))
{
son_father_wait ();
}
pthread_join(pid, NULL);
return 0;
}
更多推荐
所有评论(0)