打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Linux进程间通信示例(多通道)

使用管道进行通信

编写程序建立一个无名管道,然后生成3个子进程,使这4个进程利用同一个管道进行通信。分别试验3写1读、2写2读情况,多次执行,看结果是否一致,并对记录的执行结果进行解释。

【注】没有关于管道的示例程序(因为比较简单),在多端写入时应该使用lockf加锁。

 

 

 

一》3写1读

代码如下:

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

int pid[3];

int main(void)

{

    int fd[2];

    char outpipe[100],inpipe[100];//暂存读出,或要写入的字符串

    pipe(fd);

 

    int i;

    for(i=0;i<3;i++)

{

        pid[i]=fork( );

        if(pid[i]==0)

            break;

    }

    if(pid[1]==0)

    {

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 1 process is sending message!");   

        write(fd[1],outpipe,50);    

        sleep(5);                

        lockf(fd[1],0,0);

        exit(0);

    }

    if(pid[2]==0)

    

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 2 process is sending message!");

        write(fd[1],outpipe,50);

        sleep(5);

        lockf(fd[1],0,0);

        exit(0);

    }

   

    if(pid[3]= =0)

    

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 3 process is sending message!");

        write(fd[1],outpipe,50);

        sleep(5);

        lockf(fd[1],0,0);//释放

        exit(0);

    }

    wait(0);

    read(fd[0],inpipe,50);  

    printf("%s/n",inpipe);

 

    read(fd[0],inpipe,50);

    printf("%s/n",inpipe);

 

    read(fd[0],inpipe,50);

    printf("%s/n",inpipe);

    return 0;

}

 

运行结果:

第一次运行:

child 1 process is sending message!

child 2 process is sending message!

child 3 process is sending message!

第十五次:

child 1 process is sending message!

child 3 process is sending message!

child 2 process is sending message!

…….

(注释:因运行结果受父进程创建子进程的先后顺序影响,一般看到的结果是123,但是理论上,123,321,213等等的运行结果是会出现的,可以通过在分支前加sleep(5),来观察)

 

分析:

通过for(i=0;i<3;i++)

{

        pid[i]=fork( );

        if(pid[i]==0)

            break;

    }

可以实现父进程创建3个子进程,同时也避免了子进程再次创建子进程。

为了用wait()实现3个子进程先向管道里写入信息,然后父进程再读取。

子进程被创建后,争夺管道资源,当一个子进程抢到管道时,对其进行加锁,然后向管道里写入数据,之后解锁释放管道资源和cpu,之后父进程wait()操作。则剩下的两个子进程再争夺管道资源,直到都写入信息并父进程读出为止。

 

 

补:可见:多次执行,看结果是否一致

分析:

/==============  规定了子进程的运行顺序   ==============================

 

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

int pid1,pid2,pid3;

int main(void)

{

    int fd[2];

    char outpipe[100],inpipe[100]; //暂存读出,或要写入的字符串

    pipe(fd);

 

    //创建子进程

    while ((pid1=fork( ))= =-1);

   

    if(pid1==0)

    {

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 1 process is sending message!");   

        write(fd[1],outpipe,50);    

        sleep(5);                

        lockf(fd[1],0,0);

    }

    else

    {

        while((pid2=fork( ))= =-1);

        if(pid2==0)

        

            lockf(fd[1],1,0);

            sprintf(outpipe,"child 2 process is sending message!");

            write(fd[1],outpipe,50);

            sleep(5);

            lockf(fd[1],0,0);

        }

        else

        {

            while((pid3=fork( ))= =-1);

            if(pid3= =0)

            

                lockf(fd[1],1,0);

                sprintf(outpipe,"child 3 process is sending message!");

                write(fd[1],outpipe,50);

                sleep(5);

                lockf(fd[1],0,0);//释放

            }

            else

            {

                wait(0);

                read(fd[0],inpipe,50);  

                printf("%s/n",inpipe);

 

                read(fd[0],inpipe,50);

                printf("%s/n",inpipe);

       

                read(fd[0],inpipe,50);

                printf("%s/n",inpipe);

            }

        }

    }

    return 0;

}

 

二》2写2读

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

int pid[3];

int main(void)

{

    int fd[2], i;

    char outpipe[100],inpipe[100];//暂存读出,或要写入的字符串

    pipe(fd);

    for(i=0;i<3;i++)

{

        pid[i]=fork( );

        if(pid[i]==0)

            break;

    }

    if(pid[1]==0)

    {

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 1 process is sending message!");   

        write(fd[1],outpipe,50);    

        sleep(5);                

        lockf(fd[1],0,0);

        exit(0);

    }

    if(pid[2]==0)

    

        lockf(fd[1],1,0);

        sprintf(outpipe,"child 2 process is sending message!");

        write(fd[1],outpipe,50);

        sleep(5);

        lockf(fd[1],0,0);

        exit(0);

    }

   

    if(pid[3]==0)

    

        lockf(fd[0],1,0);

        read(fd[0],inpipe,50);

        printf("Child 3 read:\n%s/n",inpipe);

        lockf(fd[0],0,0);//释放

        exit(0);

    }

    wait(0);

    read(fd[0],inpipe,50);  

    printf("Parent read:\n%s/n",inpipe);

    exit(0);

}

运行结果:

Child 3 read:

Child 1 process is sending message!

Parent read:

Child 2 process is sending message!

 

(注释:因运行结果受父进程创建子进程的先后顺序影响,一般看到的结果如上,但是理论上,

Child 3 read:

Child 2 process if sending message!

Parent read:

Child 1 process is sending message!

 

 

等其他运行结果是会出现的。而且读不到的情况也有可能出现,比如先创建子进程1,若设1为读。当1被创建后,1抢到了管道资源并给予加锁,但此时管道中无可读数据,1执行sleep()释放cup,父进程得到cup创建过子进程2,3,2,3因得不到管道资源无法向管道中写入数据,则1占用管道但无法从管道中读出数据,父进程又等子进程先执行玩。此时,就发生了死锁。

 

结果分析:

通过for(i=0;i<3;i++)

{

        pid[i]=fork( );

        if(pid[i]==0)

            break;

    }

 

可以实现父进程创建3个子进程,同时也避免了子进程再次创建子进程。子进程1,2向管道中写入数据,子进程3和父进程从管道中读出数据并输出。

为了用wait()实现3个子进程先执行,1、2抢占管道资源并向管道中写入信息,然后父进程和子进程3从管道中读出信息并输出。

 

子进程被创建后,父进程再次执行wait()操作让子进程先执行,三个子进程争夺管道资源,当子进程1抢到管道时,对其进行加锁,然后向管道里写入数据,之后解锁释放管道资源和cpu,子进程3获得cup和管道后,从管道中读出数据并输出。子进程1抢到管道时,对其进行加锁,然后向管道里写入数据,之后解锁释放管道资源和cpu。子进程执行完,父进程获得cup和管道后,从管道中读出数据。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
linux下的umask( )函数、setsid( )函数
多进程编程小例子(YC)
Linux进程间通信
linux中使用命名管道实现客户端/服务器模型的进程间通信
Unix编程常见问题解答
Linux系统管道和有名管道的通信机制
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服