进程控制

进程创建

  • fork
    • fork有两个返回值
    • 父子进程代码共享,数据独有,私有一份(采用写实拷贝技术)
      在这里插入图片描述
      新创建的子进程几乎但不完全与父进程相同。子进程得到与父进程用户级虚拟地址空间相同的(但是独立的)一份副本,包括代码和数据段、堆、共享库以及用户栈。子进程还获得与父进程任何打开文件描述符相同的副本,这就意味着当父进程调用fork时,子进程可以读写父进程中打开的任何文件。父进程和新创建的子进程之间最大的区别在于它们有不同的PID。
int main(){
	int x = 1;
	if(fork() == 0){
		printf("p1: x = %d\n",++x);
	}
	printf("p2: x = %d\n",--x);
	exit(0);
}

在这里插入图片描述
程序运行的结果为啥是这个呢?
这道题的关键点是父进程只执行第六行的printf,所以输出的是p2:x = 0
子进程执行了两个printf语句。在fork返回之后,它执行第四行的printf,然后它从if语句中出来,执行第六行的printf。所以会输出
在这里插入图片描述

  • vfork
    • 父子进程共用一块虚拟地址空间,阻塞父进程直到子进程exit退出或程序替换重新开辟自己的空间以及虚拟地址空间页表。
      在这里插入图片描述

    进程终止

    • 进程常见退出方法
      • 正常退出(结果符合预期/结果不符合预期)
        • 从main返回
        • 调用exit:库函数,退出进程的时候先刷新缓冲区,然后释放资源
          在这里插入图片描述
          在这里插入图片描述
        • 调用_exit:系统调用接口,退出时直接释放资源
          在这里插入图片描述
          在这里插入图片描述
      • 异常退出:常见的程序崩溃
        • crtl+c,信号终止

      进程等待

      • 进程等待:等待子进程的改变(等待子进程的退出)- 获取子进程的返回值,避免僵尸进程
        1 //这是一个实现进程等待的demo                                                                                                      
        2 #include<stdio.h>
        3 #include<stdlib.h>
        4 #include<unistd.h>
        5 #include<string.h>
        6 #include<errno.h>
        7 #include<sys/wait.h>
        8 int main(){
        9   int pid = fork();
       10   if(pid<0){
       11     //error是一个全局变量,存储每次系统调用出现错误原因编号
       12     //strerror通过错误编号获取字符串错误原因
       13     printf("fork error:%s\n",strerror(errno));
       14     //perror直接打印上一个系统的调用错误原因
       15     perror("fork perror");
       16   }else if(pid == 0){
       17     sleep(3);
       18     exit(111);
       19   }
       20   //pid_t wait(int* status);
       21   //阻塞等待任意一个子进程退出,获取返回值
       22  // wait(NULL);
       23  // pid_t waitpid(pid_t pid,int* status,int options);
       24  // 阻塞等待任意一个子进程或者指定的子进程退出
       25  // pid:-1:等待任意一个子进程  pid>0:等待指定子进程
       26  // options:WNOHANG:将waitpid设置为非阻塞,0是默认阻塞
       27   //返回值:若WNOHANG被指定,没有子进程退出则立即报错返回0;错误:-1;
       28   int statu;
       29   while( waitpid(-1,&statu,WNOHANG) == 0){
       30     //非阻塞轮询操作
       31     printf("drink water\n");
       32     sleep(1);
       33   }
       34   if((statu&0x7f) == 0){
       35     printf("exit code:%d\n",(statu>>8)&0xff);
       36   }
       37   if(WIFEXITED(statu)){
       38     printf("exit code:%d\n",WEXITSTATUS(statu));
       39   }
       40   while(1){
       41     printf("i am parent\n");
       42     sleep(1);
       43   }
       44   return 0;
       45 }                
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值