进程间利用管道进行通信:打印斐波那契数列

本文介绍了一个C语言程序,该程序通过创建两个子进程来生成Fibonacci序列并展示目录详情。子进程P1使用exec()显示当前目录的信息;子进程P2生成指定长度的Fibonacci序列并通过管道将数据发送给父进程,由父进程负责打印序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fibonacci序列是0, 1, 1, 2, 3, 5, 8, .... ,通常它可以表示为:

f ib0 = 0

f ib1 = 1

f ibn= f ibn1 + f ibn2

编写一个C程序,使用系统调用fork()创建两个子进程P1P2。他们的任务如下:

1)       子进程P1打印自己的pid,然后使用exec(族)系统调用显示当前目录下文件和子目录的详细信息。

2)       子进程P2中生成Fibonacci序列,序列的个数在程序命令行中作为参数传入,例如,参数为7,则子进程P2生成的Fibonacci序列为01235813。通过某种进程通信机制(共享内存、管道、消息等IPC机制),子进程P2把生成的Fibonacci序列发送给父进程,并由父进程输出(打印)Fibonacci序列。在父子进程通信的过程中必须实现同步,以使在子进程完成生成序列之前,父进程不会输出Fibonacci序列。使用wait()系统调用可以实现进程间的简单同步。执行必要的错误检查以保证不会接受命令行参数传递来的负值。


采用fork()创建进程,进程在创建的时候共享了父进程的所有资源,包括PC程序计数器,这时候父子进程的程序计数器都是pid=fork()的等号上,也即MOVE操作上,只不过返回的值在内核代码中区分了返回的不同,父进程得到了>0的一个Pid_t,子进程为0.

通过pipe命令,利用管道进行通信

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc,const char* argv[])
{
    if(argc != 2)  //防止报错
    {
        printf("please cin a number :%s\n",argv[0]);
        exit(EXIT_SUCCESS);
    }
    pid_t childpid1,childpid2;
    int pfd[2];//管道
    int n = atoi(argv[1]); //获得参数
    childpid1 = fork();
    if( childpid1 < 0)
    {
        perror("fork_child1");
        exit(EXIT_FAILURE);
    }
    else if( childpid1 == 0)
    {
        printf("childpid1 is:%d",getpid());
        execlp("/bin/ls", "/bin/ls", "-R", ".", NULL);
    }
    else
    {
        pipe(pfd);
        wait(NULL);
        childpid2 = fork();
        if(childpid2  < 0)
        {
            perror("fork_child2");
            exit(EXIT_FAILURE);
        }
        else if( childpid2 == 0)
        {
            int next = 1;
            int now = 0;
            int tmp = 0;
            int i;
            close(pfd[0]);
            for(i = 0; i < n; i++)
            {
                write(pfd[1],&now,sizeof(now));
                tmp = now;
                now = next;
                next += tmp;
            }
        }
        else
        {
            wait(NULL);
            close(pfd[1]);
            int i;
            int status;
            for(i = 0; i < n-1; i++)
            {
                int ret;
                ret = read(pfd[0],&status,sizeof(status));
                if(ret < 0)
                {
                    perror("read");
                    exit(EXIT_FAILURE);
                }
                printf("%d、",status);
            }
            int ret = read(pfd[0],&status,sizeof(status));
            if(ret < 0)
            {
                perror("read");
                exit(EXIT_FAILURE);
            }
            printf("%d\n",status);
        }
    }
    return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值