【linux高级程序设计】(第九章)进程间通信-管道 3

有名管道

无名管道和有名管道:

1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置。

2.管道是单向的。

3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置

4.无名管道一般只用于亲缘关系进程间通信;有名管道以磁盘文件的方式存在,可以实现本机任意两进程间通信。

shell创建有名管道

mknod 管道名 p  //创建名为PIPETEST的有名管道 mknod为命令 p是参数,表示有名管道

指令 > 管道名 &   //将指令结果输入到到管道文件中

指令 < 管道名      //以指定管道名中的内容做为输入

编程实现有名管道

int mkfifo (__const char *__path, __mode_t __mode):建立的有名管道文件必须之前不存在, mode是该文件的权限。成功返回0,否则返回-1.

通过read(), write()实现读写操作。

其阻塞方式见下图(我懒得打字了,就上图吧....)

例子:

写进程

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

#define FIFO_NAME "/tmp/my_fifo"       //要创建的有名管道的路径
int main(int argc, char * argv[])
{
    int pipe_fd;
    int res;
    char buffer[] = "hello world!";
    if(access(FIFO_NAME, F_OK) == -1)   //文件是否存在
    {
        res = mkfifo(FIFO_NAME, 0766);    //创建管道
        if(res != 0)
        {
            fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
            exit(EXIT_FAILURE);
        }
    }
    printf("Process %d opening FIFO O_WRONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, O_WRONLY);    //打开有名管道
    printf("the file‘s descriptor is %d\n", pipe_fd);
    if(pipe_fd != -1)
    {
        res = write(pipe_fd, buffer, sizeof(buffer));  //写数据
        if(res == -1)
        {
            fprintf(stderr, "Write error on pipe\n");
            exit(EXIT_FAILURE);
        }
        printf("write data is %s, %d bytes is write\n", buffer, res);
        close(pipe_fd);
    }
    else
        exit(EXIT_FAILURE);
    printf("Process %d finished\n", getpid());
    exit(EXIT_SUCCESS);
}

读进程

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

#define FIFO_NAME "/tmp/my_fifo"       //要创建的有名管道的路径
int main(int argc, char * argv[])
{
    int pipe_fd;
    int res;
    char buffer[4096];
    int bytes_read = 0;
    memset(buffer, ‘\0‘, sizeof(buffer));
    printf("Process %d opening FIFO O_RDONLY\n", getpid());
    pipe_fd = open(FIFO_NAME, O_RDONLY);    //打开有名管道
    printf("the file‘s descriptor is %d\n", pipe_fd);
    if(pipe_fd != -1)
    {
        bytes_read = read(pipe_fd, buffer, sizeof(buffer));
        printf("the read data is %s\n", buffer);
        close(pipe_fd);
    }
    else
        exit(EXIT_FAILURE);
    printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
    exit(EXIT_SUCCESS);
}

运行时,先在一个终端运行写进程,此时写进程会阻塞。

ctrl+alt+[F1-F6]切换终端,在新终端运行读进程。

读进程端结果为

再切换回原终端,写进程也执行完毕。

时间: 2024-10-22 23:30:57

【linux高级程序设计】(第九章)进程间通信-管道 3的相关文章

javascript高级程序设计 第九章-- 客户端检测

javascript高级程序设计 第九章-- 客户端检测 客户端检测是javascript开发中最具争议的一个话题,由于浏览器间存在差别,通常需要根据不同浏览器的能力分别编写不同的代码.有下列常使用的客户端检测方法:能力检测:在编写代码之前先检测特定浏览器的能力.例如,脚本在调用某个函数之前,可能要先检测该函数是否存在.这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上.能力检测无法精确地检测特定的浏览器和版本.怪癖检测:怪癖实际上是浏览器中存

Linux程序设计学习笔记----进程间通信——管道

转载请注明出处: http://blog.csdn.net/suool/article/details/38444149, 谢谢! 进程通信概述 在Linux系统中,进程是一个独立的资源管理单元,但是独立而不孤立,他们需要之间的通信,因此便需要一个进程间数据传递.异步.同步的机制,这个机制显然需要由OS来完成管理和维护.如下: 1.同一主机进程间数据交互机制:无名管道(PIPE),有名管道(FIFO),消息队列(Message Queue)和共享内存(Share Memory).无名管道多用于亲

javascript高级程序设计 第一章--javascript简介

javascript高级程序设计 第一章--javascript简介Netscape开发的javascript最初的目的就是处理由服务器负责的一些输入验证操作,而在js问世之前,必须                    把表单数据发到服务器端用户才能得到反馈.如今的js不再局限于简单的数据验证,而且具备了与浏览器窗口及其内容等所有方面的交互能力,js已经发展成功能全面的面向客户端的编程语言.javascript由Netscape公司开发,原名Livescript,是为了迎合当时的java热,所

Linux与云计算——第二阶段Linux服务器架设 第九章:Mail电子邮件服务器架设—postfix和Dovecot

Linux与云计算--第二阶段Linux服务器架设 第九章:Mail电子邮件服务器架设-postfix和Dovecot 安装Postfix 安装Postfix来配置SMTP服务器. SMTP使用25/TCP. [1] Postfix 是CentOS系统默认安装,哪怕你选择了最小安装,如果确认没有安装,请先安装. [[email protected] ~]# yum -y install postfix [2] 使用Dovecot's SASL 来配置SMTP认证. [[email protect

【linux高级程序设计】(第九章)进程间通信-管道 2

文件描述符重定向 cat<test01  :将输入重定向到test01文件 cat>test02<test01  :将标准正确输出重定向到test02文件,输入设备重定向到test01文件.如果test02存在会覆盖内容.输出文件不存在会自动创建. cat>>test02<test01  :输出追加到test02 cat>test02 2>error <test01  :将标准输出重定向到test02文件,错误输出重定向到error文件.均是被覆盖.2

【linux高级程序设计】(第十一章)System V进程间通信 4

共享内存 共享内存主要用于实现进程间大量数据传输. 共享内存的数据结构定义: 系统对共享内存的限制: 共享内存与管道的对比: 可以看到,共享内存的优势: 1.共享内存只需复制2次,而管道需要4次 2.共享内存不需要切换内核态与用户态,而管道需要. 共享内存效率高! int shmget (key_t __key, size_t __size, int __shmflg) :创建共享内存 第一个参数:key值 第二个参数:欲创建的共享内存段的大小(字节) 第三个参数:shmflg创建标识,包括IP

【linux高级程序设计】(第十一章)System V进程间通信 1

System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 BSD).然而,随着一些并不基于这两者代码的UNIX实现的出现,例如 Linux 和 QNX, 这一归纳不再准确. System V IPC基础 System V 的IPC机制主要有消息队列.信号量和共享内存3种机制. shell中的 ipcs 命令可以查看当前系统中正在使用的IPC工具. shell中的 ip

【linux高级程序设计】(第十一章)System V进程间通信 3

信号量通信机制 可以看到,跟消息队列类似,也是包括两个结构. int semget (key_t __key, int __nsems, int __semflg) : 创建信号量集合 第一个参数:ftok产生的key值 第二个参数:创建的信号量个数 第三个参数:权限信息 创建信号量例子: #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/ipc.h> #include&

【linux高级程序设计】(第十二章)Linux多线程编程

线程与进程对比 1.用户空间对比 2.内核空间资源对比 在创建线程时,Linux内核仍然创建一个新的PCB来标识这个线程.内核并不认为进程与线程有差别. 进程是操作系统管理资源的基本单元,线程时Linux系统调度的基本单元. 3.进程线程函数对比 创建线程 int pthread_create (pthread_t *__restrict __newthread, __const pathread_attr_t *__restrict __attr, void *(*__start_routin