Linux 管道的用法

说明:

Linux的管道用于进程间的通信,进程通过PIPE函数,在内核中创建管道,而管道是一个单向队列。

PIPE函数注意:

1. 管道是创建在内存中的,进程结束,空间释放,管道就不存在了

2. 管道中的动心,读完了就删除了,是一个单向队列

3. 如果管道中没有东西可读,会读阻塞

4. 当我们写的内容超过管道的空间时,会产生写阻塞

5. 写管道是fd[1],读管道是fd[0]

 

先说明 一个管道的case,创建一个管道,单一进程,并写入字符串,再读出字符串

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

int main()
{
    int fd[2];
    int ret;
    char writebuf[]="Hello linux";
    char readbuf[128]={0};
    ret = pipe(fd);

    if(ret<0)
    {
        printf("creat pipe failed\n");
    }
    printf("creat pipe success!,the fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);

    write(fd[1],writebuf,sizeof(writebuf));
    //start read from the pipe
    read(fd[0],readbuf,128);
    printf("Readbuf = %s\n",readbuf);

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

    return 0;
}

编译结果如下:

love@ubuntu:~/workspace/PIPECase$ gcc pipe_2.c 
love@ubuntu:~/workspace/PIPECase$ ./a.out 
creat pipe success!,the fd[0]=3,fd[1]=5
Readbuf = Hello linux

 

无名管道就是一个队列,入队为写,出队为读。无名管道是存在内核中,进程间所有的通信都是在内核间,不是在用户空间。

进程——PIPI函数——内核——管道——读写端(用户端就是文件描述符)

可以用pid_t 定义进程,然后用fork创建进程。pid_t pid; pid = fork();根据pid的返回值确定父子进程

对于无名管道,无法实现非父子进程的通信

PIPE(2)                    Linux Programmer's Manual                   PIPE(2)

NAME
       pipe, pipe2 - create pipe

SYNOPSIS
       #include <unistd.h>

       int pipe(int pipefd[2]);

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <fcntl.h>              /* Obtain O_* constant definitions */
       #include <unistd.h>

       int pipe2(int pipefd[2], int flags);

DESCRIPTION
       pipe()  creates  a pipe, a unidirectional data channel that can be used
       for interprocess communication.  The array pipefd is used to return two
       file  descriptors  referring to the ends of the pipe.  pipefd[0] refers
       to the read end of the pipe.  pipefd[1] refers to the write end of  the
       pipe.   Data  written  to  the write end of the pipe is buffered by the
       kernel until it is read from the read end of  the  pipe.   For  further
 Manual page pipe(2) line 1/165 17% (press h for help or q to quit)

 

 

管道文件

mkfifo

int mkfifo(const char* fllename, mode_t mode)

有名管道、字符设备、块设备、套接字是不占用磁盘空间只有iNode号

mkfifo 并没有在内核空间创建管道,只有用到open打开这个节点时才会生成这样一个管道。

通过有名管道实现无亲缘关系进程之间的通信

 

 

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

int main()
{
    int ret ;
    ret = mkfifo("./myFIFO",0777);
    if(ret < 0)
    {
        printf("Creat the fifo file failed !\n");
        return -1;
    }
    printf("Creat the fifo file success .\n");

    return 0;
}

 

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

int main()
{
    int fd;
    char processs_inter = 0;
    fd = open("./myFIFO",O_WRONLY);
    if(fd < 0)
    {
        printf("failed");
    }
    printf("success\n");

    for(int i = 0;i <5;i++)
    {
        printf("This is the frist process i=%d\n",i);
        usleep(100);
    }

    processs_inter = 1;
    sleep(5);
    write(fd,&processs_inter,1);

    while(1);
    int ret ;

    return 0;
}
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
    int fd;
    char process_inter = 0;
    fd = open("./myFIFO",O_RDONLY);
    if(fd <0)
    {
        printf("failed ");

    }
    printf("success");
    read(fd,&process_inter,1);
    while(process_inter == 0);
    for(int i = 0;i <5;i++)
    {
        printf("This is the frist process i=%d\n",i);
        usleep(100);
    }
    while(1);
    int ret ;

    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值