有名管道和无名管道

合集下载

【最新精选】有名管道(FIFO)

【最新精选】有名管道(FIFO)

2.10. 有名管道(FIFO)能做什么?2.10.1. 什么是有名管道?有名管道是一个能在互不相关进程之间传送数据的特殊文件。

一个或多个进程向内写入数据,在另一端由一个进程负责读出。

有名管道是在文件系统中可见的,也就是说ls可以直接看到。

(有名管道又称FIFO,也就是先入先出。

)有名管道可以将无关的进程联系起来,而无名的普通管道一般只能将父子进程联系起来——除非你很努力地去尝试——当然也能联系两个无关进程。

有名管道是严格单向的,尽管在一些系统中无名管道是双向的。

2.10.2. 我如何建立一个有名管道?在shell下交互地建立一个有名管道,你可以用mknod或mkfifo命令。

在有些系统中,mknod产生的文件可能在/etc目录下,也就是说,可能不在你的目录下出现,所以请查看你系统中的man手册。

[译者注:在Linux下,可以看一下fifo(4)]要在程序中建立一个有名管道:/* 明确设置umask,因为你不知道谁会读写管道 */umask(0);if (mkfifo("test_fifo", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGR P)){perror("mkfifo");exit(1);}也可以使用mknod。

[译者注:在Linux下不推荐使用mknod,因为其中有许多臭虫在NFS下工作更要小心,能使用mkfifo就不要用mknod,因为mkfifo()是POSIX.1 标准。

]/* 明确设置umask,因为你不知道谁会读写管道 */umask(0);if (mknod("test_fifo",S_IFIFO | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,0)){perror("mknod");exit(1);}2.10.3. 我如何使用一个有名管道?使用有名管道十分简单:你如同使用一个普通文件一样打开它,用read()和write()进行操作。

进程间通信方式特点

进程间通信方式特点

进程间通信⽅式特点
1.⽆名管道( pipe ):管道是⼀种半双⼯的通信⽅式,数据只能单向流动,⽽且只能在具有亲缘关系的进程间使⽤。

进程的亲缘关系通常是指⽗⼦进程关系。

2.⾼级管道(popen):将另⼀个程序当做⼀个新的进程在当前程序进程中启动,则它算是当前程序的⼦进程,这种⽅式我们成为⾼级管道⽅式。

3.有名管道 (named pipe) :有名管道也是半双⼯的通信⽅式,但是它允许⽆亲缘关系进程间的通信。

4.消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。

消息队列克服了信号传递信息少、管道只能承载⽆格式字节流以及缓冲区⼤⼩受限等缺点。

5.信号量( semophore ) :信号量是⼀个计数器,可以⽤来控制多个进程对共享资源的访问。

它常作为⼀种锁机制,防⽌某进程正在访问共享资源时,其他进程也访问该资源。

因此,主要作为进程间以及同⼀进程内不同线程之间的同步⼿段。

6.信号 ( sinal ) :信号是⼀种⽐较复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣。

7.共享内存( shared memory ) :共享内存就是映射⼀段能被其他进程所访问的内存,这段共享内存由⼀个进程创建,但多个进程都可以访问。

共享内存是最快的 IPC ⽅式,它是针对其他进程间通信⽅式运⾏效率低⽽专门设计的。

它往往与其他通信机制,如信号两,配合使⽤,来实现进程间的同步和通信。

8.套接字( socket ) :套解字也是⼀种进程间通信机制,与其他通信机制不同的是,它可⽤于不同机器间的进程通信。

Linux进程通信-无名管道与有名管道

Linux进程通信-无名管道与有名管道

Linux进程通信-⽆名管道与有名管道⽆名管道(PIPE)和有名管道(FIFO)都是UNIX进程间通信(InterProcess Communication,简称IPC)的⼿段。

⽆名管道PIPE管道特点管道通常指⽆名管道,是IPC最古⽼的形式。

管道有何特点?1. 半双⼯通信,具有固定的读端、写端(单向传输数据);2. 管道只能在具有公共祖先的2个进程间使⽤,通常是⽗⼦进程;管道的创建管道由pipe函数创建,见#include <unistd.h>/* fd返回2个⽂件描述符:fd[0]为读⽽打开;fd[1]为写⽽打开。

fd[1]的输出是fd[0]的输⼊ */int pipe(int fd[2]);/* 提供位元选项可设置。

flags=0时,pipe2同pipe。

* 常⽤选项:O_NONBLOCK*/int pipe2(int fd[2], int flags);通过fd[0]调⽤read()读取数据的⼀端,叫读端;通过fd[1]调⽤write()写数据的⼀端进程,叫写端。

通常的创建模型:int pipefd[2];ret = pipe(pipefd);fork();管道的状态同⼀个进程使⽤管道没有意义,因为管道专门⽤于进程间通信。

进程内的通信使⽤全局变量即可。

要实现⽗⼦进程的通信,创建管道后,需要关闭⼀个读端,⼀个写端。

⽐如⼀个从⽗进程到⼦进程的管道,⽗进程关闭fd[0],⼦进程关闭fd[1]。

单进程半双⼯管道(⽆意义状态)fork⼦进程后的半双⼯管道(创建后的初始状态)⽗进程到⼦进程的管道(理想状态)管道的使⽤规则当管道的⼀端被关闭后,下⾯的规则起作⽤:1. 读端和写端都可以对应多个进程,但通常⼀个管道只有⼀个读进程和⼀个写进程;2. 当读⼀个写端已关闭的管道时,在所有数据都被读取后,read返回0,表⽰⽂件结束(只要还有⼀个写端还有进程,就不会产⽣⽂件的结束);3. 如果写⼀个读端已关闭的管道,会产⽣信号SIGPIPE。

无名管道和有名管道区别

无名管道和有名管道区别

2011-06-08 21:45linux 管道 FIFO——写的很全,转来的pipe是Linux中最经典的进程间通信手段,在终端里通常用来组合命令,例如“ls -l|wc -l”。

它的作用很直观,就是使得前一个进程的输出作为后一个进程的输入,在概念上很符合“管道”的意思。

用管道实现“ls -l | wc -l”《情景分析》上有这个例子的代码,我觉得很适合用来了解管道。

这里假设终端对应的进程为PA,wc、ls是PA先后创建的两个子进程child_B与child_C。

代码简化后抄录如下:int main(){int pipefds[2], child_B, child_C;pipe(pipefds);if (!(child_B=fork()){ //先创建“读”的一端,它要关闭“写”的的一端close(pipefds[1]);close(0);dup2(pipefds[0], 0); //在执行系统调用execve后,child_B会释放0,1,2之外由父进程打开的文件,close(pipefds[0]); //所以要把pipefds[0]复制到标准输入对应的文件句柄0 execl("/usr/bin/wc", "-l", NULL);} //这里之后,A和B可以通过管道进行通信close(pipefds[0]);if (!(child_C=fork()){ //再创建“写”的一端,它要关闭“读”的的一端close(1);dup2(pipefds[1],1); //道理同前面close(pipefds[1]);execl("/bin/ls", "-1", NULL);} //这里之后,B和C可以通过管道进行通信close(pipefds[1]);wait4(child_B, NULL, 0, NULL);return 0;}FIFOFIFO就是命名管道,或有名管道。

无名管道和有名管道创建通信原理

无名管道和有名管道创建通信原理

无名管道和有名管道创建通信原理
无名管道和有名管道是操作系统中常见的进程间通信方式。

无名管道只能在父子进程或者兄弟进程之间通信,而有名管道则可以在不相关的进程之间通信。

在创建管道时,操作系统会为管道创建一个缓冲区,进程可以将数据写入缓冲区或者从缓冲区读取数据。

无名管道和有名管道的创建通信原理是类似的,下面分别介绍。

1. 无名管道创建通信原理
无名管道是通过调用系统调用pipe()来创建的。

该函数会返回两个文件描述符,分别用于读取和写入管道。

在父进程中创建管道后,可以通过fork()创建子进程,并把管道文件描述符传递给子进程。

这样,父进程和子进程就可以通过管道进行通信了。

父进程写入数据时,会将数据写入管道缓冲区中,并通知管道读取进程可以读取数据了。

子进程读取数据时,会从管道缓冲区中读取数据并进行处理。

2. 有名管道创建通信原理
有名管道是通过调用系统调用mkfifo()来创建的。

该函数会创建一个文件,并返回文件描述符。

进程可以像操作普通文件一样对有名管道进行读写操作。

不同的是,当进程写入数据时,数据会被放入管道缓冲区中,并等待其他进程进行读取。

多个进程可以同时对同一个有名管道进行读写操作。

当有进程向管道写入数据时,其他进程可以通过读取管道来获取数据。

总结:无名管道和有名管道都是通过操作系统提供的系统调用来
创建的。

无名管道只能在父子进程或兄弟进程之间通信,而有名管道可以在不相关的进程之间通信。

管道创建后,进程可以通过文件描述符对管道进行读写操作,实现进程间通信。

进程间通信的几种方式

进程间通信的几种方式

进程间通信的几种方式
进程间通信是指在不同进程之间传递数据或信息的过程。

它是操作系统中非常重要的一部分,因为在现代计算机系统中,通常会有多个进程同时运行,而这些进程之间需要进行数据交换和协同工作。

以下是几种常见的进程间通信方式:
1. 管道:管道是一种基于文件描述符的通信方式,可以在父子进程之间或者兄弟进程之间传递数据。

管道有两种类型:有名管道和无名管道。

有名管道可以在不同的进程之间共享,而无名管道只能在具有亲缘关系的进程之间使用。

2. 共享内存:共享内存是指将一块内存空间映射到多个进程的地址空间中,这样多个进程就可以直接访问同一块内存数据。

共享内存的优点是速度快、数据共享直接,但同时也存在一些问题,如同步和互斥等。

3. 信号量:信号量是一种基于计数器的同步机制,用于进程之间的协调。

进程可以通过信号量来控制共享资源的访问,从而避免竞争条件和死锁等问题。

信号量通常需要与其他通信方式一起使用,如共享内存。

4. 消息队列:消息队列是一种先进先出的数据结构,可以在不同的进程之间传递消息。

进程可以将消息放入队列中,另一个进程可以从队列中读取这些消息。

消息队列的优点是可靠性高、数据传输有序,但同时也存在一些问题,如消息的格式和大小限制等。

总的来说,不同的进程间通信方式各有优缺点,我们需要根据
具体的需求和场景来选择最适合的通信方式。

linux管道通信(C语言)

linux管道通信(C语言)
int pipe_fd[2];
char buf_r[200];
memset(buf_r,0,sizeof(buf_r));
if(pipe(pipe_fd)<0;
return -1;
}
result=fork();
if(result<0){
printf("创建子进程失败");
Linux系统提供了丰富的进程通信手段,如信号、信号灯、管道、共享内存、消息队列等,能有效地完成多个进程间的信息共享和数据交换。管道作为最早的进程间通信机制之一,可以在进程之间提供简单的数据交换和通信功能。
2 管道技术简介
2.1 管道的概念及特点
管道分为无名管道和有名管道两种。无名管道可用于具有亲缘关系进程间的通信,如父子进程、兄弟进程。有名管道克服了管道没有名字的限制,允许无亲缘关系进程间的通信。本文应用的是无名管道通信机制。
exit(0);
}
else{
close(pipe_fd[0]);
if(write(pipe_fd[1],"**Hello world !**",17)!=-1)
printf("父进程向管道写入**Hello world !**\n");
if(write(pipe_fd[1]," **Welcome !**",15)!=-1)
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。
接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。

有名管道和无名管道

有名管道和无名管道

实验七有名管道和无名管道1.实验目的(1)理解进程通信机制中有名管道和无名管道的实现原理(2)掌握管道的建立、读、写等函数的使用(3)掌握有名管道和无名管道实现进程之间的通信2.实验环境已安装Linux操作系统的微机一台3.实验内容编写程序:(1) 编写管道通信程序:要求主进程创建子进程后,在子进程中调用exec函数执行一个新程序前,通过管道给即将执行的程序传递命令行参数,包括:exit,子进程退出;getpid,获取进程号等。

(2)编写有名管道程序:实现写进程获得从键盘输入的数据,读进程获得从写进程端读的数据并显示在屏幕中。

○1源代码:#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(){int pid;int pd[2];char msg_rec[10];char* message;if(pipe(pd)==-1)perror("pipe");pid=fork();if(pid==-1)perror("fork");else if(pid==0){//message="exit";message="getpid";// printf("send exit\n");printf("send getpid\n");printf("pid=%d\n",getpid());write(pd[1],message,10);exit(EXIT_SUCCESS);}else if(pid>0){sleep(1);if((read(pd[0],msg_rec,10))==-1){perror("read"); exit(EXIT_FAILURE);}printf("%s\n",msg_rec);execl("./newcode","newcode",msg_rec,(void*)0);printf("%s\n",msg_rec);exit(1);wait(NULL);}return 0;}程序的运行结果如下所示:○2源代码:#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<stdlib.h>#include<stdio.h>#define FIFO "/tmp/fifo"main(){pid_t pid;char buffer[80];int fd;unlink(FIFO);mkfifo(FIFO,0744);if(pid=fork()>0){fd=open(FIFO,O_WRONL Y);fgets(buffer,sizeof(buffer),stdin);write(fd,buffer,sizeof(buffer));printf("this is father write data is %s",buffer);printf("father's pid is %d\n",getpid());close(fd);exit(EXIT_SUCCESS);}else if(pid==0){sleep(2);fd=open(FIFO,O_RDONL Y);read(fd,buffer,80);printf("this is child read data is:%s\n",buffer);close(fd);printf("child's pid is %d\n",getpid());exit(EXIT_SUCCESS);}else{perror("fork");exit(EXIT_FAILURE);}}程序运行结果如下所示:4.实验总结通过本次实验理解了进程通信机制中有名管道和无名管道的实现原理,有名管道和无名管道实现通信的区别,以及文件描述符重定向和流重定向;掌握了管道的建立、读、写等函数的使用,掌握了有名管道和无名管道实现进程之间的通信。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验七有名管道和无名管道
1.实验目的
(1)理解进程通信机制中有名管道和无名管道的实现原理
(2)掌握管道的建立、读、写等函数的使用
(3)掌握有名管道和无名管道实现进程之间的通信
2.实验环境
已安装Linux操作系统的微机一台
3.实验内容
编写程序:
(1) 编写管道通信程序:要求主进程创建子进程后,在子进程中调用exec函数执行一个新程
序前,通过管道给即将执行的程序传递命令行参数,包括:exit,子进程退出;getpid,获取进程号等。

(2)编写有名管道程序:实现写进程获得从键盘输入的数据,读进程获得从写进程端读的数据并显示在屏幕中。

○1源代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pid;
int pd[2];
char msg_rec[10];
char* message;
if(pipe(pd)==-1)
perror("pipe");
pid=fork();
if(pid==-1)perror("fork");
else if(pid==0){
//message="exit";
message="getpid";
// printf("send exit\n");
printf("send getpid\n");
printf("pid=%d\n",getpid());
write(pd[1],message,10);
exit(EXIT_SUCCESS);
}
else if(pid>0)
{
sleep(1);
if((read(pd[0],msg_rec,10))==-1)
{perror("read"); exit(EXIT_FAILURE);}
printf("%s\n",msg_rec);
execl("./newcode","newcode",msg_rec,(void*)0);
printf("%s\n",msg_rec);
exit(1);
wait(NULL);
}
return 0;
}
程序的运行结果如下所示:
○2源代码:
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<stdio.h>
#define FIFO "/tmp/fifo"
main()
{
pid_t pid;
char buffer[80];
int fd;
unlink(FIFO);
mkfifo(FIFO,0744);
if(pid=fork()>0)
{
fd=open(FIFO,O_WRONL Y);
fgets(buffer,sizeof(buffer),stdin);
write(fd,buffer,sizeof(buffer));
printf("this is father write data is %s",buffer);
printf("father's pid is %d\n",getpid());
close(fd);
exit(EXIT_SUCCESS);
}
else if(pid==0)
{
sleep(2);
fd=open(FIFO,O_RDONL Y);
read(fd,buffer,80);
printf("this is child read data is:%s\n",buffer);
close(fd);
printf("child's pid is %d\n",getpid());
exit(EXIT_SUCCESS);
}
else
{
perror("fork");
exit(EXIT_FAILURE);
}
}
程序运行结果如下所示:
4.实验总结
通过本次实验理解了进程通信机制中有名管道和无名管道的实现原理,有名管道和无名管道实现通信的区别,以及文件描述符重定向和流重定向;掌握了管道的建立、读、写等函数的使用,掌握了有名管道和无名管道实现进程之间的通信。

相关文档
最新文档