无名管道&&有名管道详解代码

简介: 无名管道&&有名管道详解代码

管道是一种文件,

无名管道:

1)没有名字的文件,没有在磁盘里面形成具体的文件

2)不能用lseek定位

3)退出程序后,程序内部的管道资源会被释放,下次运行需要在创建,才能使用

4)只能用在亲缘进程(父子,爷孙,兄弟)

5)pipe实在fork之前创建的(4个读写端口,两个读两个写,才能够实现亲缘进程双向通信)

6)无名管道是在内核空间创建出来的。

7)半双工通信(读端只能读,不能写)

8)无名管道不能用open打开

9)写操作没有原子性。(不能给他一个多进程的环境,只能进程单一的通信)

原子性(多线程操作,全局共享区:数据):一旦任务(代码—任务函数)启动,一定要做完才能做其他事情(不能打断他,不能影响他)


无名管道的API


创建一条无名管道并且给你两个文件描述符(读写的文件描述符)

pipefd[0]:读端

pipefd[1]:写端

1)创建管道

2)创建进程

3)关闭管道

示例代码:

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

int main()
{
    int pipefd[2] = {0};
    pipe(pipefd); //创建无名管道


    pid_t ret = fork(); //创建进程

    if (ret == -1)
    {
        perror("fork");
    }
    else if (ret == 0)
    {
        char msg_data[32] = {0};
        memset(msg_data, 0, 32);
        printf("请输入发给父亲的信息:");
        scanf("%s", msg_data);
        write(pipefd[1], msg_data, strlen(msg_data));
        exit(0);
    }
    else
    {
        char msg_data[32];
        memset(msg_data, 0, 32);
        read(pipefd[0], msg_data, 32);
        printf("儿子说:%s\n", msg_data);
        wait(NULL);
    }
    //关闭管道文件
    close(pipefd[0]);
    close(pipefd[1]);
    return 0;


有名管道:

有名字的管道,所有具体的文件,存放在闪存里面。

特点:

1)血缘与非血缘都可以用

2)可用open打开(才有文件描述符)

3)不能用lseek定位

4)写操作具有原子性。

5)全双工(一个管道只有一个文件描述符:读和写)

6)退出程序后,有名管道可以一直使用,直到你把管道文件删掉。 (rx xxx)

有名管道的API

代码思路:

1)第一步:

判断管道文件存不存在 — access();

  access:可以判断文件是否存在,可读,可写,可执行
  #include <unistd.h>
      /tmp/dante_fifo       F_OK
   int access(const char *pathname, int mode);
   
   pathname:文件的路径
   mode:功能选项
   R_OK
   W_OK
   X_OK
   F_OK: 文件存不存在

存在:进入第三步

不存在则进入第二步

2)第二步:

创建管道文件,进入第三步

3)第三步:

直接打开

4)第四步:

调用

read

write

发送和接收信息

5)第五步:

close 关闭管道

示例代码:


小明发送信息给小红

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define PATH "/tmp/fifo"
int main()
{
    if(access(PATH, F_OK))
    {
        umask(0000);
        //创建管道文件
        mkfifo(PATH, 0777);
    }
    //打开管道文件
    int fd = open(PATH, O_RDWR);
    if(fd == -1)
    {
        perror("open failed");
        exit(-1);
    }
    char msg_data[10];
    while(1)
    {
        memset(msg_data,0,10);
        printf("发给小红的信息:");
        scanf("%s", msg_data);
        write(fd, msg_data, strlen(msg_data));
    }
    close(fd);
    return 0;
}


小红接收到小明信息

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

#define PATH "/tmp/fifo"
int main()
{
    if(access(PATH, F_OK))
    {
        umask(0000);
        //创建管道文件
        mkfifo(PATH, 0777);
    }
    //打开管道文件
    int fd = open(PATH, O_RDWR);
    if(fd == -1)
    {
        perror("open failed");
        exit(-1);
    }
    char msg_data[10];
    while(1)
    {
        memset(msg_data,0,10);
        printf("小红接收到小明的信息:");
        read(fd, msg_data, 10);
        printf("%s\n", msg_data);
    }
    close(fd);
    return 0;
}

.

代码实现效果:

相关文章
|
6月前
|
Linux
【linux进程间通信(一)】匿名管道和命名管道
【linux进程间通信(一)】匿名管道和命名管道
|
6月前
|
消息中间件 安全 Unix
【进程通信】进程通信--匿名管道
【进程通信】进程通信--匿名管道
|
6月前
|
Linux C语言
Linux进程间通信(fifo有名管道)
Linux进程间通信(fifo有名管道)
258 0
|
消息中间件 Unix Linux
Linux进程间通信【匿名管道和命名管道】
Linux进程间通信,包括匿名管道和命名管道的原理、操作及实现,两种管道实现进程池等丰富内容,详细讲解,干货满满!
281 2
Linux进程间通信【匿名管道和命名管道】
|
消息中间件 Unix Linux
进程间通信之管道(匿名管道与命名管道)
首先我们先提出一个问题:进程之间为什么无法直接通信,而需要操作系统提供通信方式: 经过我们上一个博客学习我们可以知道,每个进程都有独立的虚拟地址空间,一个进程在访问一个数据的时候都是通过地址来进行访问的,进过页表映射在之后访问物理内存,因此如果想要给另一个进程传递一个数据,就要把它的地址空间传递给其他进程,因为a进程的是虚拟地址,所以b进程经过页表映射也访问不了。(这个设计的初衷是:独立虚拟空间可以更稳定)
375 0
进程间通信:命名管道
一、命名管道(FIFO) 匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。 命名管道可以从命令行上创建,命令行方法是使用下面这个命令:$ mkfifo filename命名管道也可以从程序里创建,相关函数有:int mkfifo(const char *filename,mode_t mode);   二、命名管道和匿名管道 匿名管道由pipe函数创建并打开。
1037 0