`

C语言进程间通信(二)——命名管道

阅读更多

 

FIFO也称命名管道,是一种文件类型,在文件系统中可见到。管道由于没有名字,所以只能限定在亲缘关系的进程之间的通信。而通过FIFO任意进程之间都能够进行通信了。FIFO的特点如下:

 

  • 命名管道可用于任何两个进程之间的通信,比管道灵活得多
  • 命名管道作为特殊文件存在文件系统中,当进程使用结束后仍存在文件系统,需要“手动”删除
创建一个命名管道可以用mkfifo [管道名],删除可以用unlink [管道名实现]。当然用C程序创建一个管道文件也是很方便的。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>

int main(int argc, char **argv)
{
        mode_t mode = 0666;
        if (argc != 2) {
                printf("Usage: ./mkfifo.out [NAME]\n");
                exit(-1);
        }
        if ((mkfifo(argv[1], mode)) < 0) {
                printf("mkfifo error\n");
                exit(-1);
        }
        printf("created");
        return 0;
}
 写命名管道代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<limits.h>
#include<string.h>

#define BUFS PIPE_BUF

void err_quit(char *msg) {
        printf("%s\n",msg);
        exit(-1);
}

int main(){
        int fd;
        if ((fd = open("fifo",O_WRONLY)) < 0) {
                err_quit("open error");
        }
        char buf[BUFS] = "Hello world";
        write(fd,buf,strlen(buf));
        return 0;
}
 发送消息方式如下
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<limits.h>
#include<string.h>

#define BUFS PIPE_BUF

void err_quit(char *msg) {
        printf("%s\n",msg);
        exit(-1);
}

int main(){
        int fd;
        if ((fd = open("fifo",O_RDONLY)) < 0) {
                err_quit("open error");
        }
        char buf[BUFS];
        int len = read(fd,buf,BUFS);
        if (len < 0) {
                err_quit("read error");
        }
        printf("Get: %s\n",buf);
        return 0;
}
 上面的代码都很浅显易懂的,如果有进程读打开FIFO,且FIFO内没有数据,则对设置了阻塞标志的读操作来说,将一直阻塞,如果没有设置阻塞标志,则读操作会返回-1,errno的值是EAGAIN。尽管当前FIFO中有数据,只要别的进程读操作在进行时,本进程也会阻塞。
对于设置了阻塞标志的写操作,当要写入的数据量不大于PIPE_BUF时,将保证写入的原子性,当没有进程在读FIFO,那么设置了阻塞标志的写进程也会阻塞。
分享到:
评论

相关推荐

    Linux内核源代码情景分析 (上下册 高清非扫描 )

    第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6.5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用...

    linux内核源代码情景分析

    第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6.5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用...

    linux 内核源代码分析

    第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6. 5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 第7章 基于socket的进程间通信 ...

    Linux内核情景分析(非扫描版)

    第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6. 5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书...

    Linux内核情景分析

    第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6. 5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书...

    Linux程序设计 第4版.haozip01

    第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 13.5 父进程和子进程 451 13.5.1 ...

    Linux程序设计 第4版.haozip02

    第13章 进程间通信:管道 443 13.1 什么是管道 443 13.2 进程管道 444 13.3 将输出送往popen 445 13.3.1 传递更多的数据 446 13.3.2 如何实现popen 447 13.4 pipe调用 449 13.5 父进程和子进程 451 13.5.1 ...

Global site tag (gtag.js) - Google Analytics