进程间通信——命名管道

命名管道的特点

  • 可以在不同的进程之间通信,而匿名管道只能在有亲缘关系的进程间通信;
  • 命名管道创建时相当于在系统上生成了一个管道文件,并不会随系统的退出自动删除,在不再使用时需要手动删除文件。

创建命名管道

create.c

#include <stdio.h>
#include <stdlib.h>

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

// FIFO_NAME 为命名管道文件名,不同进程间要通信必须打开同一个管道文件
#define FIFO_NAME "./fifo"


int main(){

    if(mkfifo(FIFO_NAME, 0666) < 0){
        perror("mkfifo()");
        exit(1);
    }

    puts("create OK!");
    
    exit(0);
}

运行结果

fifo_create

  • p 代表使管道文件类型

写端 / 发送端

write.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>

#define FIFO_NAME "./fifo"
#define MSG_MAX 2048

int main(){

    int fd = open(FIFO_NAME, O_WRONLY);		// 以只写方式打开管道文件
    if(fd < 0){
        perror("open()");
        exit(1);
    }

    char msg[MSG_MAX];

    int i = 0;
    for(i = 0; i < 1024; i++){	// 每隔一秒往管道里发送一条信息

        sprintf(msg, "msg : %d\n", i);
        size_t msg_len = strlen(msg);

        write(fd, msg, msg_len);

        puts("write OK!");

        sleep(1);
    }

    exit(0);
}

运行结果

只打开写端

write01

  • 由于之打开了写端,管道内的数据没有程序取出,程序阻塞在 write();

同时运行读端和写端

write02

  • 程序正常往管道内输送信息

读端 / 接收端

read.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/epoll.h>

#define FIFO_NAME "./fifo"
#define MSG_MAX 1024

int main(){

    int fd = open(FIFO_NAME, O_RDONLY);		// 以只读方式打开管道文件
    if(fd < 0){
        perror("open()");
        exit(1);
    }

	// 用 epoll 来管理管道的读事件
    int epfd = epoll_create(1);
	
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
	
	// 将事件注册到 epoll 中
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = fd;
    if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0){
        perror("epoll_ctl()");
        exit(1);
    }

    while(1){
        struct epoll_event events[8];

        int nready = epoll_wait(epfd, events, 8, -1);	// 等待读事件的到来

        if(nready < 0){	// 判断 epoll_wait() 是否出错
            perror("epoll_wait()");
            exit(1);
        }
        int i = 0;
        for(i = 0; i < nready; i++){	// 处理事件
            if(events[i].events & EPOLLIN){	// 处理读事件

                char msg[MSG_MAX];
                read(fd, msg, MSG_MAX);

                printf("read msg : %s\n", msg);
            }
            // 因为逻辑上不会存在写事件,因此不处理
        }


    }
    exit(0);
}

运行结果

只打开读端

read01

  • 只打开读端,由于没有写事件的发生,程序阻塞在 epoll_wait(),并等待发送端程序运行

同时运行读端和写端

read02

  • 程序能正常捕获到读事件的发生,并取出数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值