说明:

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;
}

 

 

 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐