Linux进程通讯之无名管道和命名管道

无名管道

#include <unistd.h>

int pipe(int pipefd[2]);

        无名管道主要用在父子进程直接进行通讯,但是只能父发子收或者父收子发,发送和接收不能同时进行。 

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

int main()
{
        int fd[2];
        int pid;

        char buf[128] = {0};

        if(pipe(fd) < 0)
        {
                printf("creat error\n");
        }

        pid = fork();
        if(pid > 0)
        {
                printf("father is writing\n");
                close(fd[0]);
                write(fd[1],"hello world",strlen("hello world"));
                wait(NULL);
        }
        else if(pid == 0)
        {
                sleep(3);
                printf("this is child read:\n");
                close(fd[1]);
                read(fd[0],buf,128);
                printf("read from father: %s\n",buf);
                exit(0);
        }
        else
        {
                printf("error\n");
        }

        return 0;
}

        管道的函数是pipe()函数,除此之外还定义了一个fd[2]的数组。这个数组的用处在于是否要进行读写。fd[1]代表写,fd[0]代表读,之前说过,无名管道不能同时收发。所以,当我们进行写的操作时,要把读给关闭,也就是close(fd[0]),读操作就相反。

         代码刚开始先调用pipe()函数创建一个管道,然后创建一个进程,用pid来接收进程id。如果pid大于0,说明进入了父进程。先把fd[0]关闭,然后用write()函数进行写入操作。然后调用wait()函数等待子进程结束。

        当pid等于0时,进入了子进程,先延时3秒防止父进程没写完。然后关闭fd[1]写的操作,随后调用read()函数读取数据到buf数组里,最后调用exit()函数退出。

CLC@Embed_Learn:~/test_11.8$ gcc test1.c 
CLC@Embed_Learn:~/test_11.8$ ./a.out
father is writing
this is child read:
read from father: hello world

        能正确读到数据。 

命名管道

#include <sys/types.h>

#include <sys/stat.h> 

int mkfifo(const char *pathname, mode_t mode); 

        命名管道可以再两个进程间相互通讯,但是和无名管道一样,不能同时进行收发。pathname是文件名,mode是文件的权限。

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


int main()
{
        int fd;
        char *str = "hello world";

        fd = open("./file2",O_WRONLY);

        if(fd == -1)
        {
                printf("creat error\n");
        }

        write(fd,str,strlen(str));

        close(fd);

        return 0;
}

        这是发送的方代码,先打开一个文件,然后把hello world写入,最后关闭文件。

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


int main()
{
        int fd;

        char buf[30] = {0};

        if(mkfifo("./file2",0600) == -1)
        {
                printf("mkfifo failuer\n");
        }


        fd = open("./file2",O_RDONLY);
        if(fd == -1)
        {
                printf("open error\n");
        }

        int n_read = read(fd,buf,30);

        printf("read %d byte from fifo, context : %s\n",n_read,buf);

        close(fd);

        return 0;
}

        这是接收方的代码,使用mkfifo()函数把发送方打开的文件设为管道并且赋予文件权限。然后打开设为管道的文件,读取数据,最后关闭文件。 

CLC@Embed_Learn:~/test_11.8$ gcc write.c -o w
CLC@Embed_Learn:~/test_11.8$ gcc read.c -o r
CLC@Embed_Learn:~/test_11.8$ ./r
mkfifo failuer
read 11 byte from fifo, context : hello world

        这是第一个终端运行的命令,进行发送的操作。

CLC@Embed_Learn:~/test_11.8$ ./w

        这是第二个终端执行的命令,非常简单,只需要运行起来就好了。 

  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六花不会哭T﹏T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值