进程创建
从已存在的进程中,创建一个具有独立地址空间的新的进程,且新创建的进程为子进程。
函数:pid_t fork(void);
1. 子进程中返回0
2. 父进程返回子进程id
3. 出错返回-1
fork之前,父进程独立执行,fork之后,父子两执行流分别执行。
fork之后,谁先执行完全由调度器决定。
vfork:
1. 创建子进程,而子进程与父进程共享地址空间。
2. 保证子进程先运行,在调用exec或exit之后父进程才可能被调度运行。
代码实现
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
7 int main()
8 {
9 int g_val=0;
10 pid_t id=fork(); //创建进程
11 if(fork<0) //创建 失败
12 {
13 perror("fork");
14 return 0;
15 }
16 else if(fork==0) //子进程
17 {
18 //child
19 g_val=100;
20 printf("child[%d] : %d : %p\n", getpid(), g_val , &g_val);
21
22 }
23 else //父进程
24 {
25 //parent
26 sleep(3); //睡着三秒再打印,此时子进程已经退出,父进程执行。
27 printf("parent[%d] : %d : %p\n",getpid(), g_val, &g_val);
28 }
29 sleep(1);
30 return 0 ;
31 }
进程终止
_exit函数(强制退出)
原型:void _exit(int status);
参数:status定义了进程的中止状态,父进程通过wait来获取该值。
exit函数(清空缓冲区)
原型:void exit(int status);
exit最后也会调用_exit,但在调用之前,还做了其他工作:
1.执行用户通过atexit或on_exit定义的清理函数
2.关闭所有打开的流,所有的缓存数据均被写入
3.调用_exit
进程退出场景:
1.代码运行完毕,结果正确;
2.代码运行完毕,结果不正确;
3.代码异常终止。
进程常见退出方法:
正常终止(可通过echo $? 查看进程退出码)
1.从main返回 2.调用exit 3._exit
异常退出:Ctrl + c,信号终止
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 int main(void)
5 {
6
7 printf("himark\n");
8 exit(0);
9 }
进程等待
- 进程等待的原因
1.子进程退出,父进程若不管不顾,就可能造成“僵尸进程”的问题,进而造成内存泄漏。
2.进程一旦变成僵尸状态,kill -9也无能为力。
3.父进程需要通过进程等待来接收子进程的退出信息,回收子进程的资源。
函数pid_t wait(int* status)
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出信息,不关心则可以设置成NULL。
函数pid_t waitpid(pid_t pid,int* status,int options);
返回值:
1. 当正常返回的时候waitpid返回收集到的子进程的进程ID;
2. 如果设置了选项WNOHANG,⽽而调⽤用中waitpid发现没有已退出的子进程可收集,则返回0;
3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。
参数设置
pid
pid=-1,等待任一个子进程,与wait等效。
pid>0,等待进程ID与pid相等的子进程。
status:
WIFEXITED:若为正常终止子进程返回的状态,则为真。
WEXITSTATUS:若WIFEXITED非零,提取子进程退出码。
options:
WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
1 #include<stdio.h>
2 #include<sys/wait.h>
3 #include<unistd.h>
4 #include<stdlib.h>
5
6 int main()
7 {
8 pid_t pid;
9 pid=fork();
10 if(pid<0)
11 {
12 printf("%s fork error\n",__FUNCTION__);
13 return 1;
14 }
15 else if(pid==0)
16 {
17 printf("child is run , pid is %d\n", getpid());
18 sleep(5);
19 exit(257);
20 }
21 else
22 {
23 int status=0;
24 pid_t ret=waitpid(-1,&status, 0);
25 printf("this is test for wait\n");
26 if(WIFEXITED(status)&&ret==pid)
27 {
28 printf("wait child 5s success, child return code is:%d\n",WEXITSTATUS(status));
29 }
30 else
31 {
32 printf("wait child failed,return \n");
33 return 1;
34
35 }
36 }
37 return 0;
38 }
39