进程通讯中的有名管道

1.有名管道:
    在文件系统种,有个管道的节点。然后两个不同进程,可以通过系统IO所提供的接口函数,去实现通讯。
    open   read/write   close

2.创建

    mkfifo(char *name,mode_t mode); 第一个参数为创建节点的名字,第二个参数为创建这个节点的访问权限

3.包含的头文件及函数

      #include <sys/select.h>        

      #include <sys/time.h>

      #include <sys/types.h>
      #include <unistd.h>

    int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
    int nfds, 这个是我们需要监听的fd最大值加1,
    fd_set *readfds这个参数是监听可读fd
    fd_set *writefds这个是监听可写的fd。
    fd_set *exceptfds监听出错的fd。
    struct timeval *timeout这个是超时的时间。

    

使用步骤:
    先声明需要监听的集合,然后 先把这个监听的集合清空,FD_ZERO(fd_set *set);,然后把我们需要监听的fd添加到刚才
    清空的这个集合里面,FD_SET(int fd, fd_set *set);

返回值:    
    返回值小于0,说明有出错。
    返回值等于0,说明超时。
    如果是大于,说明有可读的fd,然后去判断是那个fd可读。FD_ISSET(int fd, fd_set *set);如果是这个fd可读,就返回真。接下       来就去读该fd。

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);
 

例子:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main()
{
    int rfd,wfd,ret;
    char str[32];
    fd_set read_fd;//声明需要监听的集合
    struct timeval time;

    mkfifo("fifo1",0644);//创建有名管道fifo1
    mkfifo("fifo2",0644);//创建有名管道fifo2
    
    rfd = open("fifo1",O_RDONLY );//打开读的管道
    wfd = open("fifo2",O_WRONLY );//打开写的管道

    if(rfd < 0 || wfd < 0)
    {
        perror("fail to open");
        return -1;
    }
    while(1)
    {    
        FD_ZERO(&read_fd);//把这个需要监听的集合清空
        FD_SET(rfd,&read_fd);//将需要监听的rfd添加到集合里
        
        FD_SET(fileno(stdin),&read_fd); //将标准输入添加到集合里
        time.tv_sec = 5;
        time.tv_usec = 0;
        memset(str,0,32);
        ret = select(rfd+1,&read_fd,NULL,NULL,&time);//监听函数
        if(ret <= 0)
            continue;
        if(FD_ISSET(rfd,&read_fd))//判断rfd是不是在集合里
        {
            read(rfd,str,32);
            printf("--------------\n");
            printf("张三:%s\n",str);
        }
        if(FD_ISSET(fileno(stdin),&read_fd))//判断标准输入是不是在集合里
        {
            printf("--------------\n");
            fgets(str,32,stdin);
            write(wfd,str,32);
        }
    }
    close(wfd);
    close(rfd);
    return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main()
{
    int rfd,wfd,ret;
    char str[32];
    fd_set read_fd;
    struct timeval time;

    mkfifo("fifo1",0644);
    mkfifo("fifo2",0644);
    
    wfd = open("fifo1",O_WRONLY );//打开写的管道
    rfd = open("fifo2",O_RDONLY );//打开读的管道

    
    if(rfd < 0 || wfd < 0)
    {
        perror("fail to open");
        return -1;
    }
    
    while(1)
    {    
        FD_ZERO(&read_fd);
        FD_SET(rfd,&read_fd);
        FD_SET(fileno(stdin),&read_fd);
        time.tv_sec = 5;
        time.tv_usec = 0;
        memset(str,0,32);
        ret = select(rfd+1,&read_fd,NULL,NULL,&time);
        if(ret <= 0)
            continue;
        if(FD_ISSET(rfd,&read_fd))
        {
            read(rfd,str,32);
            printf("--------------\n");
            printf("李四:%s\n",str);
        }
        if(FD_ISSET(fileno(stdin),&read_fd))
        {
            printf("--------------\n");
            fgets(str,32,stdin);
            write(wfd,str,32);
        }
    }
    close(wfd);
    close(rfd);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37589838/article/details/81191595