多进程相关函数
·
一,进程号获取函数
1.getpid函数 获取进程号
用来获取当前进程的进程号

示例代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
// 获取当前进程的进程号
// printf("pid=%d\n",getpid());
// 创建子进程
pid_t pid = fork();
if (pid == -1)
{
perror("创建子进程失败");
return -1;
}
else if (pid == 0)
{
// 子进程
printf("我是子进程,我的进程号是%d\n", getpid());
}
else if (pid > 0)
{
// 父进程
printf("我是父进程,我的进程号是%d\n", getpid());
}
while(1){}
return 0;
}
2.getppid函数 获取父进程号
用来获取当前进程的父进程的进程号

二,进程退出函数
1.exit函数进程退出
exit是库函数,用于正常终止进程,且satus & 0377会被返回给父进程,C标准规定了两个常量EXIT_SUCCESS和EXIT_FAILURE可被传给exit
作用:
- 刷新缓冲区、调用钩子函数、关闭流,再退出
- status 退出状态,供父进程
wait获取

示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
#if 0
printf("hello");
//exit是一个库函数.不是一个系统调用
//所以在查看该函数的时候,是man 3 exit
//exit(0); //exit在正常退出之前.会做一系列的清理工作
exit(EXIT_SUCCESS); //exit(0)等价于exit(EXIT_SUCCESS)
while(1){}
#else
// 创建子进程
pid_t pid = fork();
if (pid == -1)
{
perror("创建子进程失败");
return -1;
}
else if (pid == 0)
{
// 子进程
while (1)
{
printf("hello\n");
sleep(1);
exit(EXIT_SUCCESS); //exit(0):正常退出
}
}
else if (pid > 0)
{
// 父进程
while (1)
{
printf("world\n");
sleep(1);
}
}
#endif
return 0;
}
2._exit函数直接退出
_exit是系统调用,直接内核退出,不刷新缓冲区、不执行 atexit 钩子

示例代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
#if 0
printf("hello");
//_exit是一个系统调用.不是一个库函数
//所以在查看该函数的时候,是man 2 _exit
_exit(0); //_exit在正常退出之前.不会做一系列的清理工作
//_exit(EXIT_SUCCESS); //_exit(0)等价于_exit(EXIT_SUCCESS)
while(1){}
#else
// 创建子进程
pid_t pid = fork();
if (pid == -1)
{
perror("创建子进程失败");
return -1;
}
else if (pid == 0)
{
// 子进程
while (1)
{
printf("hello\n");
sleep(1);
_exit(EXIT_SUCCESS); //_exit(0):正常退出
}
}
else if (pid > 0)
{
// 父进程
while (1)
{
printf("world\n");
sleep(1);
}
}
#endif
return 0;
}
三,资源回收函数
1.wait函数阻塞等待子进程结束
功能:
- 阻塞父进程,一直等任意一个子进程退出
- 获取子进程退出状态
- 自动回收僵尸进程

示例代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(int argc,const char *argv[])
{
//fork 创建子进程
pid_t pid = fork();
if(pid == -1)
{
perror("创建子进程失败");
return -1;
}
else if(pid == 0)
{
printf("我是子进程,我的进程id是%d\n",getpid());
//exit(EXIT_SUCCESS); //子进程正常退出-0
exit(1000); //子进程非正常退出.退出状态是一个非0值
}
else if(pid > 0)
{
int status = 0; //保存子进程的状态值
//pid_t wait_ret = wait(NULL); //等待子进程的结束.不关注子进程的状态
pid_t wait_ret = wait(&status);
printf("我是父进程,我的进程id是%d\n",getpid());
if(wait_ret == -1)
{
perror("没有子进程或者是调用失败");
return -1;
}
printf("终止的子进程的pid是%d\n",wait_ret);
//针对于status这个子进程的退出状态码
//是需要进行宏解析的,这样的话才可以得到正确的退出状态码
//printf("子进程的退出状态值是%d\n",status);
//进行宏解析
if(WIFEXITED(status))
{
printf("子进程正常退出,退出状态码是%d\n",WEXITSTATUS(status));
}
else if(WIFSIGNALED(status))
{
printf("子进程非正常退出(子进程被信号终止),退出状态码是%d\n",WTERMSIG(status));
}
}
return 0;
}
wait函数状态解析宏
子进程正常退出:
- WIFEXITED(wstatus):若子进程是正常终止(调用 exit()/_exit() 或从 main() 返回),则返回 true
- WEXITSTATUS(wstatus):仅当WIFEXITED为 true 时使用,返回子进程的退出状态码(即exit(n)中的n,取低 8 位);
子进程被信号终止:
- WIFSIGNALED(wstatus):若子进程是被信号终止(如SIGKILL等),则返回 true;
- WTERMSIG(wstatus):仅当WIFSIGNALED为 true 时使用,返回导致子进程终止的信号编号(如9对应SIGKILL);
- WCOREDUMP(wstatus):仅当WIFSIGNALED为 true 时使用,若子进程终止时产生了核心转储文件,则返回 true;
子进程被信号暂停:
- WIFSTOPPED(wstatus):若子进程是被信号暂停(仅在使用 WUNTRACED 标志或子进程被跟踪时有效),则返回 true;
- WSTOPSIG(wstatus):仅当 WIFSTOPPED 为 true 时使用,返回导致子进程暂停的信号编号(如 19 对应 SIGSTOP);
子进程被恢复运行:
- WIFCONTINUED(wstatus):若子进程是通过SIGCONT 信号恢复运行,则返回 true;
2.waitpid函数指定等待某个子进程
优势:可以不阻塞、可以指定等待某个子进程,多进程开发必用。

示例代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, const char *argv[])
{
// 创建子进程 --完成:让父进程以非阻塞的方式等待子进程退出
pid_t pid = fork();
if (pid == -1)
{
perror("创建子进程失败\n");
return -1;
}
else if (pid == 0)
{
// 子进程
printf("我是子进程.我开始执行...\n");
sleep(6); // 延时6秒
printf("我是子进程,我执行完毕...\n");
exit(EXIT_SUCCESS); // 子进程正常退出
}
else if (pid > 0)
{
// 父进程
printf("我是父进程.我开始执行...\n");
while (1)
{
// 父进程等待子进程的退出
// 父进程在非阻塞下等待子进程的退出
//非阻塞模式本质上就是在循环轮询子进程的状态
pid_t ret = waitpid(-1, NULL, WNOHANG);
if (ret == -1)
{
perror("父进程等待子进程失败\n");
return -1;
}
else if (ret == 0) // 只有在非阻塞模式下才判断返回值为0的情况
{
printf("父进程非阻塞等待子进程,子进程没有退出\n");
sleep(1); //休眠1秒再次进行检查
}
else if (ret > 0)
{
printf("父进程非阻塞等待子进程,子进程退出了\n");
break; //退出循环
}
}
}
return 0;
}
options
0:阻塞等待WNOHANG:非阻塞,没有子进程退出立刻返回 0
waitpid函数状态解析宏
子进程正常退出:
- WIFEXITED(wstatus):若子进程是正常终止(调用 exit()/_exit() 或从 main() 返回),则返回 true;
- WEXITSTATUS(wstatus):仅当WIFEXITED为 true 时使用,返回子进程的退出状态码(即exit(n)中的n,取低 8 位);
子进程被信号终止:
- WIFSIGNALED(wstatus):若子进程是被信号终止(如SIGKILL等),则返回 true;
- WTERMSIG(wstatus):仅当WIFSIGNALED为 true 时使用,返回导致子进程终止的信号编号(如9对应SIGKILL);
- WCOREDUMP(wstatus):仅当WIFSIGNALED为 true 时使用,若子进程终止时产生了核心转储文件,则返回 true;
子进程被信号暂停:
- WIFSTOPPED(wstatus):若子进程是被信号暂停(仅在使用 WUNTRACED 标志或子进程被跟踪时有效),则返回 true;
- WSTOPSIG(wstatus):仅当 WIFSTOPPED 为 true 时使用,返回导致子进程暂停的信号编号(如 19 对应 SIGSTOP);
子进程被恢复运行:
- WIFCONTINUED(wstatus):若子进程是通过SIGCONT 信号恢复运行,则返回 true;
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)