进程间通讯 --- 管道(半双工通信)

管道:

一个进程输出数据到另一个进程数据输入的通道。(半双工通信:同一时间,只能一端读另一端写,因为只有一条信道)

有名管道(命令管道):

在磁盘上会存在一个管道文件标识,但管道文件不占用磁盘block空间,数据会缓存在内存上

可应用于同一台主机上的有权限访问的任意n个进程间通讯。(必须有一对读写进程

 有名管道使用:

创建管道文件:

     命令   mkfifo 文件名

     函数:int mkfifo(const char * pathname, int mode);

打开:open();write(); read(); close();

创建管道文件:

注意:

必须有一对读-写,只读或只写则会阻塞。

如果所有的读端关闭,则写端也会退出,反之亦然。

读写的次数没有直接联系。

如果写端保持但没有写数据(管道文件没有数据),读端阻塞。当写端将内存写满时,则写端阻塞。

一旦使用mkfifo创建了一个FIFO,就可以使用open打开它,常见的文件I/O函数都可用于fifo。如:close、read、write、unlink等。

FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。  

//进行1,写操作
int fd = open("my_fifo", O_WRONLY);  

char send[100] = "Hello Mike";
write(fd, send, strlen(send));

//进程2,读操作
int fd = open("my_fifo", O_RDONLY);//等着只写  

char recv[100] = { 0 };
//读数据,命名管道没数据时会阻塞,有数据时就取出来  
read(fd, recv, sizeof(recv));
printf("read from my_fifo buf=[%s]\n", recv);

 


无名管道(仅限父子进程):

没有管道文件标识,借助父子进程之间共享fork之前打开的文件描述符,其数据内容也是在内存上缓存。(一端写一端读)

无名管道的使用:父子进程间通讯

创建&打开: int 匹配(int fds[2]); 创建无名管道并打开,使得fds[0]为读端,fds[1]为写端;

注意:

父子进程必须关闭一对读写,并且不能是同一个进程关闭读写;

逻辑保持管道的半双工通信,防止一端关闭对应的读或写,而另一端无法感知;

#include <unistd.h>

int pipe(int pipefd[2]);
功能:创建无名管道。

参数:
    pipefd : 为 int 型数组的首地址,其存放了管道的文件描述符 pipefd[0]、pipefd[1]。
    
    当一个管道建立时,它会创建两个文件描述符 fd[0] 和 fd[1]。其中 fd[0] 固定用于读管道,而 fd[1] 固定用于写管道。一般文件 I/O的函数都可以用来操作管道(lseek() 除外)。

返回值:
    成功:0
    失败:-1

下面我们写这个一个例子,子进程通过无名管道给父进程传递一个字符串数据:  

int main()
{
    int fd_pipe[2] = { 0 };
    pid_t pid;

    if (pipe(fd_pipe) < 0)
    {// 创建管道
        perror("pipe");
    }

    pid = fork(); // 创建进程
    if (pid == 0)
    { // 子进程
        char buf[] = "I am mike";
        // 往管道写端写数据
        write(fd_pipe[1], buf, strlen(buf));

        _exit(0);
    }
    else if (pid > 0)
    {// 父进程
        wait(NULL); // 等待子进程结束,回收其资源
        char str[50] = { 0 };

        // 从管道里读数据
        read(fd_pipe[0], str, sizeof(str));

        printf("str=[%s]\n", str); // 打印数据
    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值