Linux高级编程——进程通信(管道pipe)

管道(Pipe)——特殊文件

同步实现同一台机器上的两个进程之间同步传输大量数据。

int pipe(int pipefd[2]);

[0]为读,[1]为写

管道分为两种:

  • 匿名管道(只能用于具有亲缘关系的进程间通信)

  • 命名管道(就是磁盘上的一个特殊文件,任何知道该文件路径的进程都可以使用它进行通信)

    mkfifo 管道名
    

    上述命名创建一个以管道名而生成的命名管道文件,类型为p;

    若使用cat 读取文件内容,此时,该文件则会清空;

    管道只要有人读取数据,则读取到的数据在管道中直接消失,全部读完则管道清空。

子进程会自动继承父进程的所有打开的文件描述符、文件创建掩码、当前工作目录等。

三种不同的通信方式:

  • 单工通信:数据传输只能沿固定的方向进行;
  • 半双工通信:数据传输只能分时双向
  • 全双工通信:数据传输可以同时双向传输

//匿名管道实例

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

int main()
{
    int fd[2];
    char msg[100];

    if(-1 == pipe(fd))
    {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();

    if(pid == -1)
    {
        perror("fork");
        return 2;
    }

    if(pid == 0) 
    {
        // 子进程
        read(fd[0], msg, sizeof(msg));
        printf("父进程说:%s\n", msg);

        strcpy(msg, "You are SB !\n");
        write(fd[1], msg, strlen(msg));

        close(fd[0]);
        close(fd[1]);
    }
    else 
    {
        int ret;
        // 父进程
        // sleep(1);
        strcpy(msg, "你是傻子!");
        write(fd[1], msg, sizeof(msg));

        sleep(1);

        ret = read(fd[0], msg, sizeof(msg));
        if(ret >= 0) msg[ret] = '\0';
        printf("子进程说:%s\n", msg);        

        close(fd[0]);
        close(fd[1]);
    }

    return 0;
}

//命名管道实例

//代码1
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

int main()
{
    char msg[100];

    mkfifo("./dj", 0666);

    int fd = open("./dj", O_RDWR);

    strcpy(msg, "你是傻子!");
    write(fd, msg, sizeof(msg));

    sleep(1);

    read(fd, msg, sizeof(msg));
    printf("他说:%s\n", msg);    

    close(fd);

    unlink("./dj");

    return 0;
}

//代码2
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>


int main()
{
    char msg[100];

    int fd = open("./dj", O_RDWR);

    read(fd, msg, sizeof(msg));
    printf("他说:%s\n", msg);

    strcpy(msg, "You are SB !");
    write(fd, msg, sizeof(msg));

    close(fd);

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
管道是一种进程间通信(IPC)机制,在Linux系统下非常常见。下面是一个简单的例子演示如何利用管道实现两个进程之间的通信: ```c #include <stdio.h> #include <unistd.h> #include <string.h> int main() { int fd[2]; char buf[100]; // 创建管道 if(pipe(fd) == -1) { perror("pipe"); return -1; } pid_t pid = fork(); if(pid == -1) { perror("fork"); return -1; } else if(pid == 0) { // 子进程 close(fd[1]); // 子进程关闭写端 while(1) { memset(buf, 0, sizeof(buf)); read(fd[0], buf, sizeof(buf)); // 从管道中读取数据 printf("child process received: %s", buf); } } else { // 父进程 close(fd[0]); // 父进程关闭读端 while(1) { printf("please input a message: "); fgets(buf, sizeof(buf), stdin); // 从标准输入读取数据 write(fd[1], buf, strlen(buf)); // 向管道中写入数据 } } return 0; } ``` 在这个例子中,我们使用`pipe()`函数创建了一个管道,然后通过`fork()`函数创建了一个子进程和一个父进程。子进程和父进程各自关闭了不需要的文件描述符,然后通过`read()`和`write()`函数在管道中进行数据的读写。父进程从标准输入读取数据,然后写入管道,子进程从管道读取数据并输出到终端上。这样就实现了两个进程之间的简单通信。 需要注意的是,管道有一定的容量限制,当管道被写满时,写入操作将会阻塞,直到读取了部分数据才能继续写入;同样,当管道为空时,读取操作也会阻塞,直到有新的数据写入才能继续读取。因此,在实际使用管道进行通信时,需要注意数据的读写顺序,以及需要设置合适的缓冲区大小,避免出现阻塞等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值