【Linux】进程的创建、终止和等待

进程创建

fork函数

fork函数从已存在的进程中创建一个新进程。新进程为子进程,原进程为父进程。

#include <unistd.h>
pid_t fork(void);
  • fork函数返回值:父进程返回子进程的pid,子进程返回0,出错返回-1。
  • 进程调用fork,当控制转移到内核中fork代码之后,内核会分配新的内存块和内核数据结构给子进程,将父进程部分数据结构内容拷贝至子进程,添加子进程到系统进程列表中,fork返回,开始调度器调度。
  • 写时拷贝,通常,父子代码共享,父子在不写入时,数据也共享,但任意一方试图写入,便以写实拷贝的方法各自私有一份。
  1 #include <iostream>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 using namespace std;
  6 
  7 int main()
  8 {
  9     pid_t id = fork();
 10     if(id < 0){
 11         cerr << "fork error" << endl;
 12     }
 13     else if(id == 0){
 14         cout << "i am a child!" << endl;
 15         exit(1);
 16     }
 17     else{
 18         cout << "i am parent!" << endl;
 19         sleep(2);
 20     }
 21     return 0;
 22 }  
进程终止

进程退出场景

  • 代码跑完,结果正确
  • 代码跑完,结果不正确
  • 代码没跑完,异常终止

进程常见退出方法

echo $? //查一个进程退出时的退出码

1.正常终止

(1) 从main返回(main函数返回值=当前进程退出码)

(2) 调用exit(任何地方调用exit,都表示当前进程退出)

#include <unistd>
void exit(int status)
  • exit最后也会调用exit,但在调用之前,执行用户通过aexit或on_exit的清理函数;然后冲刷缓冲,关闭流等。

(3) _exit(直接终止进程,之前的数据不要了)

#include <unistd.h>
void _exit(int status);
  • status定义了进程的终止状态,父进程通过wait获取
  • status仅有低8位可以被父进程所用。如_exit(-1)的返回值是255。

2.异常退出

  • ctrl + c,信号终止

3.return退出

  • return是一种常见的退出进程方法,执行return n等同于执行exit(n),因为调用main函数的运行时函数会将main的返回值当做exit的参数。
进程等待

wait方法

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int* status)
  • 返回值:成功返回被等待进程的pid,失败返回-1。
  • 参数:输出型参数,获取子进程退出状态,不关心则设为NULL。

waitpid方法

pid_t waitpid(pid_t pid, int* status, int options)
  • 返回值:正常返回收集到的子进程的进程id;如果设置了WNOHANG,调用的waitpid发现没有已退出的子进程,返回0;出错返回-1。
  • pid = -1,等待任一子进程,与wait等效;pid > 0, 等待起进程id与pid相等的子进程。
  • WIFEXITED(status):退出信号。
  • WEXITSTATUS(status):退出码。
  • options:wait等待的方式有两种,一种是阻塞方式,一种是非阻塞方式。
  1. 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
  2. 如果在任意时刻调用wait/waitpid,子进程且正常运行,进程可能阻塞。
    如果不存在该子进程,则立即返回出错。

具体代码实现:

进程的阻塞等待方式:

#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/wait.h>
  6 
  7 int main()
  8 {
  9     pid_t id = fork();
 10     if(id < 0)
 11     {
 12         printf("fork error\n");
 13     }
 14     else if(id == 0)
 15     {
 16         printf("child is runnning..., pid : %d\n", getpid());
 17         sleep(5);
 18         exit(13);
 19     }
 20     else
 21     {
 22         printf("parent is running..., ppid : %d\n", getppid());
 23         int status = 0;
 24         pid_t ret = waitpid(-1, &status, 0);
 25         if(ret < 0)
 26         {
 27             printf("wait error\n");
 28         }
 29         else
 30         {
 31             printf("success!\n");
 32             sleep(5);
 33         }
 34     }
 35     return 0;
 36 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值