Linux命名管道通信实例

理解代码:

/**
    suck 端简单实现
*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/select.h>
#include<fcntl.h>//读取方式宏定义
#include<sys/stat.h>//用户权限宏定义
#include<time.h>
int main(){
        int i,rfd,wfd,len=0,fd_in;
        char str[32];
        int flag,stdinflag;
        //a file describe set
        fd_set write_fd,read_fd;
        struct timeval wait_time;
        //create and give power
        mkfifo("fifo1",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
        mkfifo("fifo2",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
        //这里需要注意打开FIFO读端会产生阻塞,直到它的写端打开
        wfd=open("fifo1",O_WRONLY);
        rfd=open("fifo2",O_RDONLY);
        if(rfd<=0||wfd<=0)
                return 0;
        printf("suck client!\n");
        while(1){
                FD_ZERO(&read_fd);//初始化文件描述符集合中的各个文件描述符
                FD_SET(rfd,&read_fd);//管道fifo1的读端文件描述符添加到文件描述符集合
                FD_SET(fileno(stdin),&read_fd);//将标准输入文件描述符添加到集合
                wait_time.tv_sec=5;//设置检测时间
                wait_time.tv_usec=0;//应该是微秒的意思
                memset(str,0,sizeof(str));
                //select检测集合中是否有可读的东西,检测时间为5m,超时或错误则continue
                if(i=select(rfd+1,&read_fd,NULL,NULL,&wait_time)<=0)
                        continue;
                //memset检测时会将没有内容的文件描述符去除
                //如果rfd即管道内有可读内容则执行
                if(FD_ISSET(rfd,&read_fd)){
                        read(rfd,str,sizeof(str));
                        printf("===============\n");
                        printf("message from dog:%s\n",str);
                }

                //如果键盘有输入
                if(FD_ISSET(fileno(stdin),&read_fd)){
                        printf("==========\n");
                        fgets(str,sizeof(str),stdin);
                        len=write(wfd,str,strlen(str));
                }
        }
        close(rfd);
        close(wfd);
        return 0;
}
/**
dog端简单实现
*/
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<time.h>
#include<sys/select.h>
int main(){
        int i,rfd,wfd,len=0,fd_in;
        char str[32];
        int flag,stdinflag;
        fd_set read_fd,write_fd;
        struct timeval wait_time;
        mkfifo("fifo1",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
        mkfifo("fifo2",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
        rfd=open("fifo1",O_RDONLY);
        wfd=open("fifo2",O_WRONLY);
        if(rfd<=0||wfd<=0)
                return 0;
        printf("dog client!\n");
        while(1){
                FD_ZERO(&read_fd);
                FD_SET(rfd,&read_fd);
                FD_SET(fileno(stdin),&read_fd);
                wait_time.tv_sec=5;
                wait_time.tv_usec=0;
                memset(str,0,sizeof(str));
                if(i=select(wfd+1,&read_fd,NULL,NULL,&wait_time)<=0)
                        continue;
                if(FD_ISSET(rfd,&read_fd)){
                        read(rfd,str,sizeof(str));
                        printf("==============\n");
                        printf("message from suck:%s\n",str);
                }
                if(FD_ISSET(fileno(stdin),&read_fd)){
                        printf("===============\n");
                        fgets(str,sizeof(str),stdin);
                        len=write(wfd,str,strlen(str));
                }

        }
        close(rfd);
        close(wfd);
        return 0;
}

运行结果: 

 

总结:需要注意一个地方 ,在两个客户端的代码中有两端需要多理解。

        wfd=open("fifo1",O_WRONLY);
        rfd=open("fifo2",O_RDONLY);

        rfd=open("fifo1",O_RDONLY);
        wfd=open("fifo2",O_WRONLY);

在阻塞模式下,FIFO只有在读写端同时打开时才会返回,否则会一直阻塞。所以fifo1和fifo2顺序不能一个在前一个在后,如果一前一后会导致程序1和2都卡在等另外的端口打开。这好像是产生死锁的四个必要条件中的,循环等待条件

  • 互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。
  • 不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。
  • 请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
  • 循环等待条件 在发生死锁时必然存在一个进程等待队列{P1,P2,…,Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所深情地资源。 
    以上给出了导致死锁的四个必要条件,只要系统发生死锁则以上四个条件至少有一个成立。事实上循环等待的成立蕴含了前三个条件的成立,似乎没有必要列出然而考虑这些条件对死锁的预防是有利的,因为可以通过破坏四个条件中的任何一个来预防死锁的发生。

里面主要的函数用法可以自行百度Google,也可参考:https://blog.csdn.net/cstarbl/article/details/7645298

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值