‘壹’ linux系统的进程间通信有哪几种方式
数据传输
一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间
共享数据
多个进程想要操作共享数据,一个进程对共享数据
通知事
一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
资源共享
多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。
进程控制
有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
Linux 进程间通信(IPC)的发展
linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。
前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,通信进程局限在单个计算机内;
后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。
Linux则把两者继承了下来
早期UNIX进程间通信
基于System V进程间通信
基于Socket进程间通信
POSIX进程间通信。
UNIX进程间通信方式包括:管道、FIFO、信号。
System V进程间通信方式包括:System V消息队列、System V信号灯、System V共享内存
POSIX进程间通信包括:posix消息队列、posix信号灯、posix共享内存。
由于Unix版本的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix标准,这个新的ANSI Unix标准被称为计算机环境的可移植性操作系统界面(PSOIX)。现有大部分Unix和流行版本都是遵循POSIX标准的,而Linux从一开始就遵循POSIX标准;
BSD并不是没有涉足单机内的进程间通信(socket本身就可以用于单机内的进程间通信)。事实上,很多Unix版本的单机IPC留有BSD的痕迹,如4.4BSD支持的匿名内存映射、4.3+BSD对可靠信号语义的实现等等。
linux使用的进程间通信方式
管道(pipe),流管道(s_pipe)和有名管道(FIFO)
信号(signal)
消息队列
共享内存
信号量
套接字(socket)
管道( pipe )
管道这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
流管道s_pipe: 去除了第一种限制,可以双向传输.
管道可用于具有亲缘关系进程间的通信,命名管道:name_pipe克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
信号量( semophore )
信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
消息队列( message queue )
消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号 ( singal )
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
主要作为进程间以及同一进程不同线程之间的同步手段。
共享内存( shared memory )
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
套接字( socket )
套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信
更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
进程间通信各种方式效率比较
类型
无连接
可靠
流控制
记录消息类型
优先级
普通PIPE N Y Y N
流PIPE N Y Y N
命名PIPE(FIFO) N Y Y N
消息队列 N Y Y Y
信号量 N Y Y Y
共享存储 N Y Y Y
UNIX流SOCKET N Y Y N
UNIX数据包SOCKET Y Y N N
注:无连接: 指无需调用某种形式的OPEN,就有发送消息的能力流控制:
如果系统资源短缺或者不能接收更多消息,则发送进程能进行流量控制
各种通信方式的比较和优缺点
管道:速度慢,容量有限,只有父子进程能通讯
FIFO:任何进程间都能通讯,但速度慢
消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
信号量:不能传递复杂消息,只能用来同步
共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存
如果用户传递的信息较少或是需要通过信号来触发某些行为.前文提到的软中断信号机制不失为一种简捷有效的进程间通信方式.
但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。
无名管道简单方便.但局限于单向通信的工作方式.并且只能在创建它的进程及其子孙进程之间实现管道的共享:
有名管道虽然可以提供给任意关系的进程使用.但是由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用。
消息缓冲可以不再局限于父子进程,而允许任意进程通过共享消息队列来实现进程间通信,并由系统调用函数来实现消息发送和接收之间的同步,从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用方便,但是信息的复制需要额外消耗CPU的时间,不适宜于信息量大或操作频繁的场合。
共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。
但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的,因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中,所以只能由处于同一个计算机系统中的诸进程共享。不方便网络通信。
共享内存块提供了在任意数量的进程之间进行高效双向通信的机制。每个使用者都可以读取写入数据,但是所有程序之间必须达成并遵守一定的协议,以防止诸如在读取信息之前覆写内存空间等竞争状态的出现。
不幸的是,Linux无法严格保证提供对共享内存块的独占访问,甚至是在您通过使用IPC_PRIVATE创建新的共享内存块的时候也不能保证访问的独占性。 同时,多个使用共享内存块的进程之间必须协调使用同一个键值。
‘贰’ linux:无名管道通信实验
#include<unistd.h>
#include<stdio.h>
//警告:该程序未做错误验证,未关闭管道(由系统自动关闭)
intmain()
{
intp2c[2];//该管道父进程写,子进程读
intc2p[2];//该管道子进程写,父进程读
//创建2条管道
pipe(p2c);
pipe(c2p);
intpid=fork();
intfd_read,fd_write;//这两个描述符用于保存某进程读端和写端
intpid_my;//保存某进程自身的pid
intpid_other;//另一进程的pid,通过
if(pid==0){//子进程
fd_read=p2c[0];
fd_write=c2p[1];
//通过getpid取得自身pid,写到管道里
pid_my=getpid();
write(fd_write,&pid_my,sizeof(int));
//从另一管道读取另一进程的pid
read(fd_read,&pid_other,sizeof(int));
//打印读取到的pid
printf("Recivepid:%d ",pid_other);
}else{ //p
fd_read=c2p[0];
fd_write=p2c[1];
pid_my=getpid();
//由于子进程是先写自身pid,父进程最好先读取子进程的pid
read(fd_read,&pid_other,sizeof(int));
write(fd_write,&pid_my,sizeof(int));
printf("Recivepid:%d ",pid_other);
}
return0;
}
‘叁’ Linux系统编程—管道
Linux 实现 IPC 其中的一种方式——管道
管道又分:
1、无名管道:无名管道只能用于有亲缘关系的进程。
2、有名管道:有名管道用于任意两进程间通信。
你就可以把管道理解成位于进程内核空间的“文件”。
给文件加引号,是因为它和文件确实很像,因为它也有描述符。但是它确实又不是普通的本地文件,而是一种抽象的存在。
当进程使用 pipe 函数,就可以打开位于内核中的这个特殊“文件”。同时 pipe 函数会返回两个描述符,一个用于读,一个用于写。如果你使用 fstat函数来测试该描述符,可以发现此文件类型为 FIFO。
而无名管道的无名,指的就是这个虚幻的“文件”,它没有名字。本质上,pipe 函数会在进程内核空间申请一块内存(比如一个内存页,一般是 4KB),然后把这块内存当成一个先进先出(FIFO)的循环队列来存取数据,这一切都由操作系统帮助我们实现了。
pipe 函数打开的文件描述符是通过参数(数组)传递出来的,而返回值表示打开成功(0)或失败(-1)。
它的参数是一个大小为 2 的数组。此数组的第 0 个元素用来接收以读的方式打开的描述符,而第 1 个元素用来接收以写的方式打开的描述符。也就是说,pipefd[0] 是用于读的,而 pipefd[1] 是用于写的。
打开了文件描述符后,就可以使用 read(pipefd[0]) 和 write(pipefd[1]) 来读写数据了。
注意事项
1、这两个分别用于读写的描述符必须同时打开才行,否则会出问题。
2、如果关闭读 (close(pipefd[0])) 端保留写端,继续向写端 (pipefd[1]) 端写数据(write 函数)的进程会收到 SIGPIPE 信号。
3、如果关闭写 (close(pipefd[1])) 端保留读端,继续向读端 (pipefd[0]) 端读数据(read 函数),read 函数会返回 0。
当在进程用 pipe 函数打开两个描述符后,我们可以 fork 出一个子进程。这样,子进程也会继承这两个描述符,而且这两个文件描述符的引用计数会变成 2。
如果你需要父进程向子进程发送数据,那么得把父进程的 pipefd[0] (读端)关闭,而在子进程中把 pipefd[1] 写端关闭,反之亦然。为什么要这样做?实际上是避免出错。传统上 pipe 管道只能用于半双工通信(即一端只能发,不能收;而另一端只能收不能发),为了安全起见,各个进程需要把不用的那一端关闭(本质上是引用计数减 1)。
步骤一:fork 子进程
步骤二:关闭父进程读端,关闭子进程写端
父进程 fork 出一个子进程,通过无名管道向子进程发送字符,子进程收到数据后将字符串中的小写字符转换成大写并输出。
有名管道打破了无名管道的限制,进化出了一个实实在在的 FIFO 类型的文件。这意味着即使没有亲缘关系的进程也可以互相通信了。所以,只要不同的进程打开 FIFO 文件,往此文件读写数据,就可以达到通信的目的。
1、文件属性前面标注的文件类型是 p
2、代表管道文件大小是 0
3、fifo 文件需要有读写两端,否则在打开 fifo 文件时会阻塞
通过命令 mkfifo 创建
通过函数 mkfifo创建
函数返回 0 表示成功,-1 失败。
例如:
cat 命令打印 test文件内容
接下来你的 cat 命令被阻塞住。
开启另一个终端,执行:
然后你会看到被阻塞的 cat 又继续执行完毕,在屏幕打印 “hello world”。如果你反过来执行上面两个命令,会发现先执行的那个总是被阻塞。
有两个程序,分别是发送端 send 和接收端面 recv。程序 send 从标准输入接收字符,并发送到程序 recv,同时 recv 将接收到的字符打印到屏幕。
发送端
接收端
编译
运行
因为 recv 端还没打开test文件,这时候 send 是阻塞状态的。
再开启另一个终端:
这时候 send 端和 recv 端都在终端显示has opend fifo
此时在 send 端输入数据,recv 打印。
‘肆’ 如何才能在linux下建立全双工管道
只要理解了什么是管道,就很简单了 管道“| ”就是将前面命令输出作为管道后面命令的输入 如: ls -a | grep test | awk "{print $1}" 就是将ls -a 显示的结果,在帅选出含有test,然后打印出第一列。
‘伍’ linux有名管道是双工通信吗
# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 # 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
‘陆’ 到底linux下的管道是什么
简单来说,管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性,管道又称为半双工管道。管道的这一特点决定了器使用的局限性。管道是Linux支持的最初Unix IPC形式之一。
‘柒’ linux的三种管道机制分别是什么
Linux 是一套 Unix-like 的操作系统,是 Unix 的一种,它控制整个系统基本服务的核心程序 (kernel) 是由 Linus 带头开发出来的,“Linux”这个名称便是以“Linus's unix”来命名,Linus 选择用“大众公有版权” (GPL)的方式来发行这份程序,这个版权允许任何人以任何形式复制与散布 Linux 的原始程序,换句话说,Linux 实际上是“免费的”,使用者在网络上就可以抓到 Linux 的原始程序代码,随心所欲的复制与更改 Linux 的原始程序,在因特网的日渐盛行以及 Linux 开放自由的版权之下,吸引了无数计算机高手投入开发、改善 Linux 的核心程序,使得 Linux 的功能日见强大,所以今日我们可以在网络上免费下载 Linux 使用,或者花很少的一点费用就可以取得 Linux 光盘,这都是因为 Linux 是 GPL 版权的缘故。
除了核心程序以外,一个操作系统还需要其它的系统程序跟应用程序才有实用性,Linux 系统中常用的系统程序大部份是美国自由软件基金会 (Free Software Foundation) 开发出来的软件,而且也有不少机构或个人为 Linux 开发应用程序,这些程序一样大多都是自由软件,任何人都可以免费的在网络上取得,不过自行去取得这些程序再一一安装非常不便,于是有些公司或团体就会去搜集、整合 Linux 上的程序,把“核心-系统程序-应用程序”总合起来构成一个完整的操作系统,让一般使用者可以简便的安装完整个系统,这就是所谓的“安装软件包”(distribution),我们一般讲的 Linux 系统便是针对这些安装软件包而言,同样是 Linux 系统,却分成不同公司、机构整合出来的不同安装软件包,这就是大家常常在网络上看到 Linux 有那么多“种”的原因。
Linux 具有 Unix 系统的程序接口跟操作方式,也继承了 Unix 稳定有效率的特点。网络上安装 Linux 的主机连续运做一年以上而不曾当机、不必关机是稀松平常的事,不过 Linux 却不象一般 Unix 要负担庞大的版权费用,也不需要在专属的昂贵硬件上才可以使用;Linux 可以在一般的 i386 PC 上执行,效能又高,自然而然的接收了过去几十年来在 Unix 上累积的程序资源跟使用者,加上 GPL 的版权允许大家自由散布 Linux 的原始码,并针对自己的需求修改程序,使得 Linux 在目前已经成为非常受人欢迎的一个多人多任务、免费、稳定、效率高、可以在包括 i386、Sparc、Alpha、Mips、PPC 等众多不同计算机系统平台上执行的操作系统。
Linux支持多种硬件装置,诸如x86、Motorola 68k、Digital Alpha、Sparc、Mips、Motorola PowerPC和ARM等等。由于程序代码公开,硬件厂商无须多付额外的版权费用,便得以替自行生产的硬件装置开发适用于Linux的驱动程序,提高产品销售率。
软 体方面,如X,为窗口系统的工业标准;另外,由理察·史托曼主导的Emacs,提供窗口版和文字版的文书编辑环境,功能复杂强大,有一套完整的在线说明档 案;而众人合作开发的SpreadSheet,是窗口版的电子表格,任何熟稔Lotus 1-2-3的人,看到这样丰硕的成果,都会有莫名的感动的。当然,最为人称道的,是Linux的网络能力,不论是SLIP、PPP、NetBEUI、 DDP、X.25还是ISDN等等,Linux都有相应的软件供应;而稳定的服务器功能,适用于架设Intranet和Internet。
一般用户受益于GNU GPL和LGPL的保护,可以不同的管道取得完整的Linux,故而Linux可以是“免费的(gratis)”。相对于Unix昂贵的版权费用,Linux称得上是物美价廉。
除此以外,Linux还具有如下的特色∶
· 具备多人多任务∶这表示Linux可以在同一段时间内服务许多人各别的需求。形象一点讲,你可以一边听铁达尼号的原声CD,一边编辑文书,一边又在打印档案,还可以随时玩X版的俄罗斯方块。
· 支持多CPU∶这绝对不是NT的专利,Linux也支持这种硬件架构,代表着更快速的运算和革命性的算法即将成为时代的主流。
· RAM保护模式∶程序(processes)之间不会互相干扰,保证系统能常久运作无误。根据许多人下载系统评量程序(benchmarks)以测试 Linux的执行效能,结果发现单单是配备486CPU的PC,效能便足堪媲美升阳(Sun)或是迪吉多的中级工作站了。
· 动态加载程序∶当程序加载RAM执行时,Linux仅将磁盘中相关的程序模块加载,有效地提升了执行的速率和RAM的管理。
· 动态连结共享程序馆∶这表示执行档的大小大量地减少,有助于节省磁盘空间。
· 支持多种档案系统∶如Minix、Xenix、System V等等着名的操作系统。将来NT的NTFS也会列入支持的。
· 看得见DOS∶这是所谓的透明化(transparency);把DOS的FAT档案系统视为特殊的远程档案系统,不需任何特别的指令便可以灵活运用,就如同一个在Linux底下存在的目录一样。
Linux的发展
近几年的发展,已使得Linux成为微软、升阳的另一大敌手。Linux挟其价格低廉、品质良好与稳定的竞争优势,正无形无影地扩散至众多以PC为主的工作 平台上。早期因缺乏商业性应用软件,单凭学术味道浓厚的工具程序,是无法打入一般商家的主流操作系统的。然而,今日的Linux已非吴下阿蒙,KDE、 Gimp、Gnome等计划相继地开展,为X提供了更多图形接口的桌面操作环境和应用软件。
约1993年左右,Linux首先以发行软 体(distribution)的型态出现。这是一群完整的软件,包含安装程序、核心、应用软件、X、驱动程序等的软件包,经由Internet下载至磁 盘片进行安装。那时的安装程序简陋,难以成功地安装妥当,接口亲和力不足和硬件支持不良是最大的障碍。
后来出现了光驱,光盘片的传播媒体也应运而生,现今Linux厂商所制作的发行软件也都是以此为主要的发行媒介。国内常见的有Red Hat、Slackware和Debian这三种。其中以Debian算是至今仍维持非商业型态的重量级发行软件了,FSF曾经以基金援助过其初阶段的发展。任何人都可以从Debian的FTP站上下载整套的发行软件。当然,象Red Hat这样的商业组织,Red Hat发行软件一样也可以从FTP站上下载,不过如果花一点小钱买光盘片的话,就可以得到额外的技术支持和有用的说明档案。
要得到这些光盘片,最简单的方法便是买有关Linux的书籍,不论中文版或是英文版的书本,书背面都会附上一片载有该公司或组织所制作的发行软件。一般书内多会有专章讲解安装和设定的过程,读者可善加利用。不同的发行软件有不同的安装机制,然而都是Linux。
对国内用户而言,最关切的莫过于Linux中文技术的发展情况了。X窗口系统已有稳定的中文版问世,各种中文输入法和中文仿真窗口也已进入成熟的阶段,相信未来会朝向应用软件中文化的层面发展,使X的操作环境符合国内用户的需求。
Linux的应用
没有商业活动,就没有Linux;没有信息自由的自觉,更不可能有Linux。
Linux除了是优良的软件开发平台之外,也是工作、家居的好伙伴。有人说∶“有了Linux,就等于有了阿拉神灯。”此言不假矣。又有人说∶“到现在还没有移植到Linux的软件,肯定是一点价值也没有的。”这话也不差呀。
Linux的发展证实了信息会愈来愈便宜的趋势;因为便宜,市场便无限扩张。商业活动也转向为以服务为导向的型态。最直接的案例便是ISP的应用。
Linux可以用来架设ISP!
Linux Journal的发行人SSC(Specialized System Consultants)便是以Linux做为网络拨接服务平台的。要成为ISP业者,需要有连接至因特网的能力,多序列阜拨接服务(如 Cycades、Maxspeed、Gtek等公司所提供的软件系统),PPP和SLIP的服务,Usenet新闻群组(如INN),邮件递送(如 sendmail),网页服务器(如Apache),备份功能(如tar、cpio)等等的应用软件。由此观察,主要的控制成本会落在因特网的通讯租费 上,投资Linux的费用是非常低的。
本文摘录自“ Official CLE 0.8 — 中文 Linux 延伸软件包使用指南
大力发展linux软件事业,有助于我国自主软件的开发,保护国家信息安全,并且在国际竞争中赢得一点份额
‘捌’ 什么是linux管道,windows下有管道类似的东西吗
管道是一种进程间通信机制,好比一个管子,一边一个口,一个往里放,另一头可以往出取,操作是双向的
windows也有这样的东西Pipe
‘玖’ linux中的管道的本质到底是什么呢
简单来说,管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性,管道又称为半双工管道。管道的这一特点决定了器使用的局限性。管道是Linux支持的最初Unix IPC形式之一。