操作系统 - Linux - 使用fork()函数实现三个进程并发执行

操作系统 - Linux - 使用fork()函数实现三个进程并发执行

这里三个进程是指父进程两个子进程,也就是利用fork()创建两个子进程

fork()函数介绍

1. 函数原型

#include <unistd.h>

/* Clone the calling process, creating an exact copy.
   Return -1 for errors, 0 to the new process,
   and the process ID of the new process to the old process.  */
extern __pid_t fork (void) __THROWNL;

大概意思就是:复制调用该函数的进程,创建一个相同的副本。出错返回-1,新进程(子进程)返回0,老进程(父进程)返回新进程(子进程)的PID。

2. 返回值

fork()函数比较特殊,调用一次,返回两次

  • 子进程接收到返回值为0
  • 父进程接收到返回值为子进程的PID(大于0)

3. fork()的使用

// fork()的使用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    pid_t fpid;
    if ((fpid = fork()) < 0)
    { // 出错
        printf("fork faild\n");
        exit(0);
    }
    else if (fpid == 0)
    { // 子进程执行
        printf("Child process!\n");
        // getpid()获取当前进程号, getppid()获取父进程号,fpid为fork()的返回值
        printf("PPID=%d  PID=%d  FPID=%d\n", getppid(), getpid(), fpid);
        // 进程正常终止
        exit(0);
    }
    else
    { // 父进程执行
        wait(NULL); // 父进程阻塞,等待子进程结束再继续执行
        printf("Parent process!\n");
        printf("PPID=%d  PID=%d  FPID=%d\n", getppid(), getpid(), fpid);
        exit(0);
    }
}

输出结果

Child process!
PPID=4198  PID=4203  FPID=0
Parent process!
PPID=4193  PID=4198  FPID=4203

结果分析

pid - 当前进程号

ppid - 父进程号

fpid - fork()返回值

  • 子进程的FPID为0
  • 父进程的FPID == 4203 == 子进程的PID == 4203
  • 子进程的PPID == 3934 == 父进程的PID == 3934
  • 注意wait()

使用fork()实现三个进程并发执行

1. 代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#define NUM 5 // print_msg()循环打印次数

void afterFork(int index, pid_t fpid);
void print_msg(int index, char *m);

int main(int argc, char *argv[])
{
    int index = 0; // 自定义的当前进程序号,0表示父进程,从1开始表示第1个子进程
    pid_t fpid_1 = fork(); // fork第一个子进程
    afterFork(++index, fpid_1);
    pid_t fpid_2 = fork(); // fork第二个子进程
    afterFork(++index, fpid_2);
    print_msg(0, "---"); // ---代表父进程
    wait(NULL); // 等待所有子进程结束
    return 0;
}

/**
 * @brief 父进程执行fork()函数之后的操作
 * 
 * @param index 自定义的进程序号,1表示第1个子进程,2表示第2个子进程
 * @param fpid fork()的返回值
 */
void afterFork(int index, pid_t fpid)
{
    if (fpid < 0)
    {
        printf("fork faild\n");
        exit(0);
    }
    else if (fpid == 0)
    {
        print_msg(index, "***"); // ***代表子进程
        exit(0); // 子进程退出
    }
}

/**
 * @brief 间隔1s打印信息,每个进程会循环打印NUM次
 * 
 * @param index 
 * @param sign ---代表父进程,***代表子进程
 */
void print_msg(int index, char *sign)
{
    int i;
    for (i = 0; i < NUM; i++)
    {
        printf("%sindex=%d%s\n", sign, index, sign);
        fflush(stdout);
        sleep(1); // 等待1s
    }
}

代码解释

  • 没有判断fpid > 0的情况,因为我们要先创建两个子进程然后再执行父进程的代码,所以父进程的代码(print_msg())放在了程序末尾
  • 注意子进程执行完毕后要exit(0),否则子进程又会执行另一个fork()函数再创建一个子进程中的子进程,就会各种套娃

2. 实现效果

三进程并发执行

可以看到,三个进程(几乎)是同时执行的,但是三个进程执行的前后顺序每次都可能发生变化(这也说明了确实是并发执行)

  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

insight^tkk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值