当前位置: 首页 > news >正文

实操(等待子进程)Linux

相关函数 

1. fork() 

  • 功能:创建一个新的子进程,子进程是父进程的副本(复制代码、数据段、堆栈等)
#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

返回值:
成功时父进程返回子进程的 PID(>0)
子进程返回 0
失败时返回 -1(如进程数达到限制)

2. getpid()、 getppid()

  • 功能:获取当前进程的PID(进程ID)、PPID(父进程ID)

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
返回值:当前进程的PID(始终成功)

pid_t getppid(void);
返回值:当前进程的PPID(若父进程已终止,返回系统初始化进程的PID,如 init 或 systemd)

4. sleep(unsigned int seconds)

  • 功能:使当前进程休眠指定秒数(可能被信号中断)。

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

参数:seconds——休眠的秒数

返回值:
成功休眠完毕返回 0
被信号中断时返回剩余的秒数

5. exit(int status)

  • 功能:终止当前进程,并返回状态码给父进程(通过 wait/waitpid 获取)

#include <stdlib.h>

void exit(int status);

参数:status——退出状态(低8位可被父进程捕获)

6. waitpid(pid_t pid, int status, int options)

  • 功能:等待指定子进程的状态变化(如终止或暂停)

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *wstatus, int options);

参数:
pid:
>0:等待指定PID的子进程。
-1:等待任意子进程(等价于 wait)。
0:等待与调用进程同组的子进程。
<-1:等待进程组ID为 |pid| 的任意子进程。

status:输出子进程的终止状态(需用宏如 WIFEXITED 解析)。

options:
0:阻塞等待
WNOHANG:非阻塞,若无子进程退出则立即返回。

返回值:
成功时返回 子进程PID。
WNOHANG 且无子进程退出时返回 0。
失败时返回 -1(如无子进程)。

7. WIFEXITED(int status)

  • 功能:检查子进程是否正常退出(通过 exit 或 return)。


参数:status——waitpid 获取的退出状态

返回值:
若正常退出返回 非0值(true)
否则返回 0

8. WEXITSTATUS(int status)

  • 功能:提取子进程的退出状态码(exit 或 return 的值)。

参数:status——waitpid 获取的退出状态(需先通过 WIFEXITED 检查)

返回值:子进程的退出状态码(低8位,范围 0-255)

实操

test.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

#define TASK_NUM 10

typedef void (*func_t)();
func_t other_task[TASK_NUM];

void a() { printf("正在执行a任务\n"); }
void b() { printf("正在执行b任务\n"); }
void c() { printf("正在执行c任务\n"); }

int LoadTask(func_t func)
{
    int i = 0;
    for(; i < TASK_NUM; ++i) if (other_task[i] == NULL) break;
    if (i == TASK_NUM) return -1;
    else other_task[i] = func;
    return 0;
}

void InitTask()

{
    for(int i = 0; i < TASK_NUM; ++i) other_task[i] = NULL;
    LoadTask(a);
    LoadTask(b);
    LoadTask(c);
}

void RunTask()
{
    for(int i = 0; i < TASK_NUM; ++i)
    {
        if (other_task[i] == NULL) continue;
        else other_task[i]();
    }
}

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        int cnt = 10;
        while(cnt)
        {
            printf("我是子进程,我还能跑%ds, pid: %d, ppid: %d\n", cnt--, getpid(), getppid());
            sleep(1);
            int *p = NULL;
            *p = 1;
        }
        exit(111);
    }

    InitTask();

    while(1)
    {
        int status = 0;
        pid_t ret_id = waitpid(id, &status, WNOHANG);
        if (ret_id < 0)
        {
            printf("waitpid error\n");
            exit(1);
        }
        else if (ret_id == 0)
        {
            RunTask();
            sleep(1);
            continue;
        }
        else
        {
            if (WIFEXITED(status))
                printf("wait succcess, child exit code: %d\n", WEXITSTATUS(status));
            else
                printf("wait succcess, child exit signal: %d\n", status & 0x7F);
            break;   
        }
    }


    return 0;
}

相关文章:

  • 简单了解一下Unity的Resources.UnloadUnusedAssets
  • 【从0到1学RabbitMQ】RabbitMQ高级篇
  • 脑科学与人工智能的交叉:未来智能科技的前沿与机遇
  • 制造企业数据治理体系搭建与业务赋能实践
  • oracle em修复之路
  • Qt 5.14.2入门(一)写个Hello Qt!程序
  • 如何测试两端网络是否连通?—— 实用方法与工具详解
  • Spring Bean生命周期执行流程详解
  • 对Android中zygote的理解
  • 安装OpenJDK1.8 17 (macos M芯片)
  • Qt 入门 3 之对话框 QDialog
  • 前端性能优化实战:从 Webpack 到 Vite 的全栈提速方案
  • 解锁 MCP:模型上下文协议的介绍与应用​,技术解析与应用场景
  • 顶刊【遥感目标检测】【TGRS】LSKF-YOLO:面向高分辨率卫星遥感影像电力塔检测的大规模选择性核特征融合网络
  • LeetCode hot 100—编辑距离
  • 记录一下学习docker的命令(不断补充中)
  • 微信小程序跳
  • oracle json笔记
  • 线程同步与互斥(下)
  • 关于 Spring Boot + Vue 前后端开发的打包、测试、监控、预先编译和容器部署 的详细说明,涵盖从开发到生产部署的全流程
  • wordpress改文章日期/东莞seo排名收费
  • 1000元做网站/重庆关键词优化软件
  • 国家信用信息企业公示系统官网/windows优化大师靠谱吗
  • 杭州论坛网站建设/开鲁视频
  • 滕州市中远建设工程公司网站首页/新东方线下培训机构官网
  • 只做传统嫁衣网站/郑州聚商网络科技有限公司