长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 文件操作

  • Linux进程和线程

  • Linux信号

  • 进程间通信

    • 无名管道
    • 有名管道
      • 有名管道创建函数
        • 代码示例
      • FIFO操作函数
        • 代码示例
        • 有名管道的读程序
        • 有名管道的写程序
        • 输出
        • 分析
    • 信号量
    • 共享内存
    • 消息队列
  • Socket

  • C语言
  • 进程间通信
DC Wang
2023-02-22
目录

有名管道

# 有名管道

有名管道(FIFO)存在于文件系统中,功能比无名管道强大,可以让无关联的进程交换数据。

# 有名管道创建函数

有名管道创建函数为mkfifo(与shell命令同名)。执行成功返回0,否则返回-1,并设置errno。

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode)
1
2
3

# 代码示例

// newfifo.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    mode_t mode = 0666;
    if(argc != 2) {
        puts("USAGE: newfifo {name}");
        exit(EXIT_FAILURE);
    }

    if((mkfifo(argv[1], mode)) < 0) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# FIFO操作函数

  • 打开FIFO管道:open
  • 关闭FIFO管道:close
  • 读取FIFO管道:read
  • 写入FIFO管道:write

# 代码示例

# 有名管道的读程序

// readfifo.c
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>

int main(void)
{
    int fd;    /* Descriptor for FIFO */
    int len;   /* Bytes read from FIFO */
    char buf[PIPE_BUF];
    mode_t mode = 0666;

    if((mkfifo("fifo1", mode)) < 0) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }

    /* Open the FIFO read-only */
    if((fd = open("fifo1", O_RDONLY)) < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    /* Read and display the FIFO's output until EOF */
    while((len = read(fd, buf, PIPE_BUF - 1)) > 0)
        printf("rdfifo read: %s", buf);

    close(fd);

    exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 有名管道的写程序

/*
 * wrfifo.c - Write to a "well-known" FIFO
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <time.h>

int main(void)
{
    int fd;               /* Descriptor for FIFO */
    int len;              /* Bytes written to FIFO */
    char buf[PIPE_BUF];   /* Ensure atomic writes */
    time_t tp;            /* For time call */

    /* Identify myself */
    printf("I am %d\n", getpid());

    /* Open the FIFO write-only */
    if((fd = open("fifo1", O_WRONLY)) < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    /* Generate some data to write */
    while(1) {
        /* Get the current time */
        time(&tp);
        /* Create the string to write */
        len = sprintf(buf, "wrfifo %d sends %s", getpid(), ctime(&tp));
        /* 
        * Use (len + 1) because sprintf does not count
        * the terminating null
        */
        if((write(fd, buf, len + 1)) < 0) {
            perror("write");
            close(fd);
            exit(EXIT_FAILURE);
        }
        sleep(3);
    }

    close(fd);
    exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 输出

# 终端1
$ ./readfifo
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:37 2023
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:40 2023
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:43 2023

#终端2
$ ./writefifo
I am 3591
^C

$ ls
fifo1  readfifo  writefifo
1
2
3
4
5
6
7
8
9
10
11
12
13

# 分析

readfifo中创建一个命名管道名为fifo1,打开并阻塞读取管道内容,直到有其它进程向管道中写入内容。

writefifo中打开管道fifo1,循环向其中写入进程号和当前时间信息。

编辑 (opens new window)
#Linux#进程间通信#IPC
上次更新: 2023/03/31, 22:34:04
无名管道
信号量

← 无名管道 信号量→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式