(万字长文)C语言多进程的使用

目录

进程

子进程的创建

进程信号

捕获信号

signal(2)函数

sigaction(2)函数

举个例子

发送信号

终端发送信号

程序发送信号

子进程的释放

waitpid(2)函数

wait(2)函数

举个例子


进程

系统创建进程时,会给进程一个虚拟的地址空间,让进程存储自己运行时需要的资源。同时,进程还可以创建线程,以执行自己的程序。

子进程的创建

子进程的创建采用fork(2)函数,使用时要包含unistd.h头文件:

pid_t fork(void);

这个函数将会通过复制调用进程,创建一个新进程。调用进程被称为父进程,被创建的新进程叫子进程。子进程与父进程运行在不同的地址空间。在刚创建时,两个进程的地址空间的内容一样,且互不影响。除了以下几点,子进程将会精确复制父进程:

  • 子进程有自己的唯一进程ID,这个PID与任何现有进程组的ID都不匹配。

  • 子进程的父进程ID与父进程的进程ID相同。

  • 子进程不继承其父进程的内存锁。

  • 子进程的进程资源利用率和CPU时间计数器被重置为零。

  • 子进程的待处理信号集初始为空。

  • 子进程不继承其父进程的信号量调整。

  • 子进程不继承其父进程的进程相关记录锁。

  • 子进程不继承其父进程的定时器。

  • 子进程不继承其父进程的未完成的异步I/O操作,也不继承其父进程的任何异步I/O上下文。

这里面可能有些名词不知道,不过没有关系,这些都是linux的底层操作。

 这个函数会创建一个子进程,因此,剩下的程序会在子进程和父进程中同时执行。在父进程中,它会返回子进程的进程ID;在子进程中,它会返回0.

如果创建出错,它会返回-1,并将errno的值设为对应的错误值。

以下程序演示了在父进程中创建子进程:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void){
    int test = 0;
    int *p = (int *)malloc(sizeof(int));
    *p = 0;
    // 创建一个子进程
    int pid = fork();
    if(pid == -1){
        printf("创建失败\n");
        goto ERROR;
    }
    // 判断当前进程是子进程或父进程
    if(pid == 0){
        // 演示子进程和父进程的地址空间相互独立
        printf("这是子进程\n");
        printf("子进程没有改变test的值\n");
        printf("test = %d\n", test);
        printf("*p = %d\n", *p);
    }else{
        printf("这是父进程\n");
        test = 5;
        printf("父进程已经将test变量改成了5\n");
        printf("test = %d\n", test);
        *p = 4;
        printf("父进程已经将堆区某地址的值设为了4,这个地址的指针是p\n");
        printf("*p = %d\n", *p);
    }
    // 演示子进程与父进程执行相同的代码
    printf("这可能是子进程或父进程\n");
    return 0;
    ERROR:
    return -1;
}

以下是代码的流程:

  1. 初始化一个整数 test 为 0,并动态分配地址给一个整数指针 p

  2. 创建一个子进程。

  3. 检查 fork() 的返回值以确定当前进程是子进程还是父进程。

    • 如果 fork() 返回 -1,表示进程创建失败,打印 "创建失败" 并跳到错误处理部分。

    • 如果返回值是 0,表示当前是子进程,打印 "这是子进程",并输出 test 和 *p 的值。

    • 如果返回值是正数(通常是父进程的进程ID),表示当前是父进程。

      • 打印 "这是父进程"。
      • 将 test 变量设置为 5。
      • 输出 test 的新值。
      • 将指针 p 所指向的地址设置为 4。
      • 输出 *p 的新值。
  4. 最后,无论当前是子进程还是父进程,都会打印 "这可能是子进程或父进程"。

  5. 如果出现错误,则进入错误处理部分,main函数返回 -1。

运行结果:


                
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值