LINUX进程间通信2.

合集下载

实验十八--linux进程间通信

实验十八--linux进程间通信
实验十九

共享内存(Shared memory)

消息队列(Mes种最为高效的进程间通信方式。因为进程可 以直接读写内存,不需要任何数据的拷贝。 为了在多个进程间交换信息,内核专门留出了一块内存区。 这段内存区可以由需要访问的进程将其映射到自己的私有 地址空间,从而大大提高了效率。 由于多个进程共享一段内存,因此也需要依靠某种同步机 制,如互斥锁和信号量等 。

消息队列就是一些消息的列表。用户可以从消息队列中 添加消息和读取消息等。从这点上看,消息队列具有一 定的FIFO特性,但是它可以实现消息的随机查询,比 FIFO具有更大的优势。同时,这些消息又是存在于内核 中的,由“队列ID”来标识。 消息的结构。受到两方面约束,长度必须小于系统规定 上限,其次,它必须以一个长整型变量开始,接受函数 将用这个成员变量来确定消息类型 struct my_message{ long message_type; /*data*/


共享内存的实现分为两个步骤: 第一步是创建共享内存,shmget(),从内存中获得 一段共享内存区域。 第二步是映射共享内存,shmat(),把这段创建的 共享内存映射到具体的进程空间中。


到这里可使用共享内存了,也就是可以使用不带缓 冲的I/O读写命令对其进行操作。 除此之外,当然还有断开映射的操作,shmdt()。

编写一对程序shm1.c和shm2.c,第一个程序创建 一个共享内存段,并把写到里面的数据都读出来, 直到读到“end”。第二个程序连接已有的共享内 存段,并负责向里输入数据,直到输入“end” (需要自己提供同步机制)。

编写一对程序msg1.c和msg2.c,前者负责接收消 息,后者负责发送消息,允许两个进程都可以创建 消息队列,但只有接收进程可以删除队列,规定当 接收或发送数据为“end”时结束。

linux线程间通信方式

linux线程间通信方式

linux线程间通信方式
Linux 线程间通信方式包括以下几种:
1. 管道通信:管道是一种半双工的通信方式,只能用于具有亲缘关系的进程之间的通信,父进程创建管道,在进程间传递数据。

2. 信号通信:信号是一种异步通信方式,在进程之间传递简单的信息。

一个进程向另一个进程发送一个信号,另一个进程收到信号后就可以采取相应的操作。

3. 共享内存通信:共享内存是最快的进程间通信方式,可以将内存区域映射到多个进程的地址空间中,实现进程间数据的共享。

需要注意解决信号量、锁等同步问题。

4. 信号量通信:信号量是一种计数器,用来协调多个进程对共享资源的访问。

多个进程需要对信号量进行操作,以实现对共享资源的访问控制。

5. 消息队列通信:消息队列是一种通过消息传递来进行通信的机制,可以在进程之间传递数据块,通常用于进程间的同步和异步通信。

6. 套接字通信:套接字是基于网络通信的一种进程间通信方式,可用于同一主机上进程间通信,也可以在不同主机之间通信。

套接字是基于 TCP/IP 协议栈实现的,需要在数据传输时注意网络传输和数据结构转换等问题。

以上是 Linux 线程间通信的主要方式,开发者可以根据不同的需求和场景选择合适的方式。

详解linux进程间通信-消息队列

详解linux进程间通信-消息队列

详解linux进程间通信-消息队列前⾔:前⾯讨论了信号、管道的进程间通信⽅式,接下来将讨论消息队列。

⼀、系统V IPC 三种系统V IPC:消息队列、信号量以及共享内存(共享存储器)之间有很多相似之处。

每个内核中的 I P C结构(消息队列、信号量或共享存储段)都⽤⼀个⾮负整数的标识符( i d e n t i f i e r )加以引⽤。

⽆论何时创建I P C结构(调⽤m s g g e t、 s e m g e t或s h m g e t) ,都应指定⼀个关键字(k e y),关键字的数据类型由系统规定为 k e y _ t,通常在头⽂件< s y s / t y p e s . h >中被规定为长整型。

关键字由内核变换成标识符。

以上简单介绍了IPC,对接下来介绍的消息队列、信号量和共享内存有助于理解。

⼆、消息队列 1、简介 消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。

我们将称消息队列为“队列”,其标识符为“队列 I D”。

m s g g e t⽤于创建⼀个新队列或打开⼀个现存的队列。

m s g s n d⽤于将新消息添加到队列尾端。

每个消息包含⼀个正长整型类型字段,⼀个⾮负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给 m s g s n d。

m s g r c v⽤于从队列中取消息。

我们并不⼀定要以先进先出次序取消息,也可以按消息的类型字段取消息。

2、函数介绍ftok函数#include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'功能:⽣成⼀个key(键值)msgget函数#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int msgflg);功能:创建或取得⼀个消息队列对象返回:消息队列对象的id 同⼀个key得到同⼀个对象格式:msgget(key,flag|mode);flag:可以是0或者IPC_CREAT(不存在就创建)mode:同⽂件权限⼀样msgsnd函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);功能:将msgp消息写⼊标识为msgid的消息队列msgp:struct msgbuf {long mtype; /* message type, must be > 0 */消息的类型必须>0char mtext[1]; /* message data */长度随意};msgsz:要发送的消息的⼤⼩不包括消息的类型占⽤的4个字节msgflg:如果是0 当消息队列为满 msgsnd会阻塞如果是IPC_NOWAIT 当消息队列为满时不阻塞⽴即返回返回值:成功返回id 失败返回-1msgrcv函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);功能:从标识符为msgid的消息队列⾥接收⼀个指定类型的消息并存储于msgp中读取后把消息从消息队列中删除msgtyp:为 0 表⽰⽆论什么类型都可以接收msgp:存放消息的结构体msgsz:要接收的消息的⼤⼩不包含消息类型占⽤的4字节msgflg:如果是0 标识如果没有指定类型的消息就⼀直等待如果是IPC_NOWAIT 则表⽰不等待msgctl函数int msgctl(int msqid, int cmd, struct msqid_ds *buf);msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象 程序2-2将简单演⽰消息队列: --- snd.c ---#include "my.h"typedef struct{long type;char name[20];int age;}Msg;int main(){key_t key = ftok("/home/liudw",'6');printf("key:%x\n",key);int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);if(msgid<0){perror("msgget error!");exit(-1);}Msg m;puts("please input your type name age:");scanf("%ld%s%d",&m.type,,&m.age);msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);return0;} --- rcv.c ---#include "my.h"typedef struct{long type;char name[20];int age;}Msg;int main(){key_t key = ftok("/home/liudw",'6');printf("key:%x\n",key);int msgid = msgget(key,O_RDONLY);if(msgid<0){perror("msgget error!");exit(-1);}Msg rcv;long type;puts("please input type you want!");scanf("%ld",&type);msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);printf("rcv--name:%s age:%d\n",,rcv.age);msgctl(msgid,IPC_RMID,NULL);return0;} 运⾏演⽰: 三、详解ftok函数 ftok根据路径名,提取⽂件信息,再根据这些⽂件信息及project ID合成key,该路径可以随便设置。

L-IPC

L-IPC

25


有名管道的创建可以使用函数 mkfifo(),该函 数类似文件中的open()操作,可以指定管道的路 径和打开的模式。 在创建管道成功之后,就可以使用open、read、 write这些函数了。与普通文件的开发设置一样, 对于为读而打开的管道可在open中设置 O_RDONLY,对于为写而打开的管道可在open中设 置 O_WRONLY,在这里与普通文件不同的是阻塞 问题。由于普通文件的读写时不会出现阻塞问题, 而在管道的读写中却有阻塞的可能,这里的非阻 塞标志可以在open函数中设定为 O_NONBLOCK。
26


对于读进程 若该管道是阻塞打开,且当前 FIFO 内没有数 据,则对读进程而言将一直阻塞直到有数据写 入。 若该管道是非阻塞打开,则不论 FIFO 内是否 有数据,读进程都会立即执行读操作。 对于写进程 若该管道是阻塞打开,则写进程而言将一直阻 塞直到有读进程读出数据。 若该管道是非阻塞打开,则当前 FIFO 内没有 读操作,写进程都会立即执行读操作。
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 在Alpha AXP Linux系统上,信号的编号有些不同。

浅析Linux进程通信的几种方式及其比较

浅析Linux进程通信的几种方式及其比较
摘 要: 本文通过 对 Ln x下几种主要 通信 方式进 行概述 , iu 并结合 Ln x系统的 系统调 用对 OS中的实现进行 简要概述 , iu 并对 其优缺点进行 分析 , 阐述 了在不 同通信情况 下应该 选择何 种通信 方式进行选择。
关 键 词 :iu ; 讯 方 式 Ln x 通 中图分 类号 : 3 TP 9 文献标 识 码 : A
: 兰 C ia N w T c n lge n rd cs h n e e h oo isa d P o u t
高 新 技 术
浅析 Ln x 程通 信 的几种 方式及其 比较 iu 进
曹 鹏
( 解放 军 国际 关 系学 院 , 苏 南京 2 0 3 ) 江 1 09
为数组 sp 的大小 。 os 通信 的 过程 中 , 系统 可 以利 用 M G T 0 S C L 在消 4管道 通信 方式 . 息 队列上 执行 指定 的操作 ,更 具参 数 的不 同 管 道是 Lnx 持 的最 初 U i IC形 式 和权 限 的不 同 ,可 以执行 检索 、删除 等得 操 i 支 u n P x 之一, 当两 个进 程利 用 管道 进行 通 信 时 , 送 作 。 发 信 息 的进程 称 为写 进程 ,接 收 信息 的进 程 称 共 享 的消 息 队列 是一 个 临界 资 源 ,针对 为 读进 程 。管道 通信 方 式 的 中间介 质就 是 文 同一 消息 队列 的诸 发送 和 接收 进程 必 须保 证 件 , 常称 这 种 文件 为 管 道 文 件. 它 就 像 管 互 斥 进入 ,这 种进 程 间 的同步 和互 斥 是 由系 通 道 一样 将一 个 写进程 和 一个 读 进程 连接 在 一 统 提供 的系统 调用 自动实 现 的 ,所 以用户 在 起 , 现两个 进程 之 间 的通 信 。

linux进程间通讯的几种方式的特点和优缺点

linux进程间通讯的几种方式的特点和优缺点

linux进程间通讯的几种方式的特点和优缺点Linux进程间通讯的方式有多种,其优缺点也不尽相同,接受者依赖发送者之时间特性可承载其优端。

下面就讨论几种典型的方式:1、管道(Pipe):是比较传统的方式,管道允许信息在不同进程之间传送,由一端输入,另一端输出,提供全双工式劝劝信息传送,除此之外,伺服端也可以将其服务转换为管道,例如说Web服务程序。

管道的优点:简单易懂、可靠、灵活、容易管理,可以控制发送端和接收端的信息流量。

管道的缺点:线程之间的信息量不能太大,也只能在本机上使用,不能通过网络发送信息。

2、消息队列(Message queue):消息队列主要应用在大型网络中,支持多种消息队列协议,广泛用于在远程机器上的进程间的交互、管理进程间的数据和同步问题。

消息队列的优点:主要优点是这种方式可以将消息发送给接收端,然后接收端可以从距离发送端远的地方网络上接收消息,通过消息队列可以较好的管理和控制进程间的数据流量和同步问题。

消息队列的缺点:缺点是消息队里的管理复杂,并且有一定的延迟,而且它使用时应避免共享内存,对于多处理器和跨网络环境, TCP 传输数据时也比不上消息队列的传输效率高。

3、共享内存(Share Memory):是最高效的进程间通信方式,也是最常用的,它使进程在通信时共享一个存储地址,双方都可以以该存储地址作为参数进行读写操作。

共享内存的优点:实现高性能,数据同步操作快、数据可以高速传输,可以解决多处理器以及跨网络环境的通信。

共享内存的缺点:由于进程间直接使用物理内存,没有任何保护,所需要使用较复杂的同步机制来完成数据的可靠传输。

总的来说,每种进程通讯方式都有各自的优缺点,不同的系统需求也许需要多种方案的相互配合才能有效的处理系统间通信的问题。

系统设计者应根据具体系统需求,选择合适的进程通信方式来实现更好的进程间通信。

操作系统的消息传递和进程间通信实现进程间的信息传递和通信

操作系统的消息传递和进程间通信实现进程间的信息传递和通信

操作系统的消息传递和进程间通信实现进程间的信息传递和通信操作系统是计算机中非常重要的一个组成部分,它负责管理和控制计算机的硬件和软件资源。

在多道程序设计环境下,操作系统需要负责调度和管理多个进程的执行。

而进程间的信息传递和通信是操作系统中一个关键的功能,它使得不同进程之间能够相互交互、传递数据,从而实现协同工作和资源共享。

本文将探讨操作系统中的消息传递和进程间通信,以及它们的实现方法和技术。

一、消息传递在操作系统中,进程间的信息传递可以通过消息传递的方式来实现。

消息传递是指一个进程向另一个进程发送消息,并由接收进程接收和处理该消息。

消息传递可以用于进程间的同步和通信,从而实现进程之间的交互。

消息传递一般包括以下几个步骤:1. 消息的创建:发送进程首先需要创建一条消息,并在消息中填写相应的内容。

消息可以包含数据、指令等信息,以满足不同的需求。

2. 消息的发送:发送进程将创建好的消息发送给接收进程。

发送进程需要指定接收进程的标识符,以确保消息能够被正确地发送到目标进程。

3. 消息的接收:接收进程通过等待操作等待消息的到达。

当消息到达时,接收进程将检查消息的标识符,以确定该消息是否是自己所期望接收的。

4. 消息的处理:接收进程接收到消息后,会对消息进行处理。

处理的方式取决于消息的内容和接收进程的需求。

消息传递可以有两种方式:直接消息传递和间接消息传递。

直接消息传递是指发送进程直接发送消息给接收进程。

间接消息传递是指通过操作系统的消息队列来传递消息。

不同的方式适用于不同的场景和需求。

二、进程间通信的实现为了实现进程间的信息传递和通信,操作系统提供了多种机制和技术。

以下是几种常见的进程间通信的实现方式:1. 共享内存共享内存是一种在多个进程之间共享同一块物理内存的方式。

通过将一块内存区域映射到多个进程的地址空间中,进程可以通过读写共享内存的方式来进行通信。

共享内存的优点是速度快,但需要进程之间进行同步和互斥操作,以避免数据的冲突和错误。

简述linux中进程间各种通信方式特点

简述linux中进程间各种通信方式特点

简述linux中进程间各种通信方式特点Linux中进程间通信方式有多种,包括管道,命名管道,消息队列,信号量,共享内存和套接字。

每种通信方式都有自己的特点和适用场景。

一、管道1. 特点:- 管道是最简单的进程间通信方式之一,只能用于具有父子关系的进程间通信。

- 管道是一个单向通道,数据只能在一个方向上流动。

- 管道的容量有限,在写度满之前,读进程阻塞;在读度空之前,写进程阻塞。

2. 使用场景:- 父子进程之间需要进行简单的数据传输。

二、命名管道1. 特点:- 命名管道是一种特殊类型的文件,可以实现不相关进程的通信。

- 命名管道是半双工的,只能在一个方向上传输数据。

- 命名管道是顺序读写的,进程可以按照顺序读取其中的数据。

2. 使用场景:- 不相关的进程需要进行数据传输。

- 需要按照顺序进行传输的场景。

三、消息队列1. 特点:- 消息队列是一组消息的链表,具有特定的格式和标识符。

- 消息队列独立于发送和接收进程的生命周期,可以实现不相关进程间的通信。

- 消息队列可以根据优先级进行消息的传输。

2. 使用场景:- 需要实现进程间相对复杂的数据传输。

- 数据传输具有优先级。

四、信号量1. 特点:- 信号量是一个计数器,用于实现多个进程之间的互斥和同步。

- 信号量有一个整数值,只能通过定义的操作进行访问。

- 信号量可以用于控制临界区的访问次数。

2. 使用场景:- 多个进程需要共享公共资源。

- 需要进行互斥和同步操作。

五、共享内存1. 特点:- 共享内存是一块可以被多个进程共同访问的内存区域。

- 共享内存是最快的进程间通信方式,因为数据不需要在进程之间拷贝。

- 共享内存需要通过同步机制(如信号量)进行互斥访问。

2. 使用场景:- 需要高效地进行大量数据传输。

- 数据读写频繁,需要最小化数据拷贝的开销。

六、套接字1. 特点:- 套接字是一种网络编程中常用的进程间通信方式。

- 套接字支持不同主机上的进程进行通信。

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

write(fd[1],buf,30);exit . (0);
default:wait(NULL);read(fd[0],s,30);printf(“%s―,s); } }
例2:父进程生成P1,P2两子进程分别向管道写入各自 的字符,父进程读出它们。
main() { int pid1,pid2,fd[2]; char buf[50],s[50]; pipe(fd); pid1=fork(): switch(pid1){ case –1:perror(”fork failed‖);exit(1); case 0:lockf(fd[1],1,0);//锁定写入端 sprintf(buf,”child p1 is sending messages!\n‖); write(fd[1],buf,50); . sleep(5); lockf(fd[1],0,0);//释放写入端 exit(0); default:pid2=fork();
2.有名管道
注意:无名管道 (1)pipe()的调用必须在fork()之前 (2)及时关闭不需要的句柄 (3)管道通信只能用于父子进程间。
有名管道的创建:
#mknod sampleFIFO 或#mkfifo -m 0666 sampleFIFO
.
例子:
#define FIFO-FILE ―sampleFIFO― void main(void) { FILE *fp; char readbuf[80]; mknod(FIFO-FILE,S_IFIFO|0666,0); while(1){ fp=fopen(FIFO-FILE,‖r‖); #define FIFO-FILE ―sampleFIFO― main(int argc,char *argv[]) { FILE *fp;
1.管道pipe
函数声明:int pipe(int fd[2]); 返回值:0:成功 -1:失败 功能:用系统调用pipe(fd)建立管道文件,读端 fd[0],写端fd[1],管道按照FIFO方式交换信息。 只能用于父子进程间。
pipe( fd)
写 入 端 fd[1]
.
读 出 端 fd[0] read(fd[0],buf,size)
死锁问题ቤተ መጻሕፍቲ ባይዱ
各进程在使用系统资源时应注意死锁问题。 死锁的概念:各并发进程彼此互相等待对方所拥有 的资源,且这些并发进程在得到对方的资源之前不 能继续向前推进的状态
p1
拥 有 S1
.

p2
求 S2 要 求 S1
拥 有 S2
s1 死锁的概念
s2
死锁问题
死锁的起因:系统提供的资源个数少于并发进程所要求的该 类资源数。 产生死锁的必要条件: (1)互斥条件 (2)不剥夺条件 (3)部分分配 (4)环路条件 死锁的排除法: (1)死锁的预防 . (2)死锁避免 (3)死锁的检测和恢复
Linux 环 境 下 进 程 控 制 与 通 信
Interprocess Communications(IPC) 进程通信主要有以下几种方法: 1. 管道:无名、有名


2.
3. 4.
信号量
Message queue队列编程; 共享内存编程; TCP/IP socket编程;
.
1. 5.
switch(pid2){ case –1:perror(”fork failed‖);exit(1); case 0:lockf(fd[1],1,0);//锁定写 入端 sprintf(buf,”child p2 is sending messages!\n‖); write(fd[1],buf,50);sleep(5); lockf(fd[1],0,0);//释放写入端 exit(0); default:wait(NULL); read(fd[0],s,50);printf(“%s―, s); wait(NULL);read(fd[0],s,50); printf(“%s―,s);exit(0); } }问题:如果没有lockf(),结果会 怎样?
进程的属性
1.进程标识符:为非负整数,在系统中唯一,进程 0为调度进程,进程1为初始化进程。 Pid=getpid();ppid=getppid() 2.进程组标识符:进程组对于进程间的通信机构—— 信号有用; getpgrp();某个用户退出系统时,系统根据组 标识符来选定该终止的进程。 改变进程组 newgrp=setpgrp ();所建立的新进 . 程将继承 newgrp 。这允许某些进程的生命期超出 用户的注册期。
write(fd[1],buf,size)
例1:父子进程间用管道方式通信。
main() { int pid,fd[2]; char buf[30],s[30]; pipe(fd); pid=fork():
switch(pid){
case –1:perror(”fork failed‖);exit(1); case 0:sprintf(buf,”This is an example\n‖);
进程的属性
3.进程环境 extern char ** environ; main() { char **env=environ; while(*env) printf("%s\n",*env++); } 进程的当前目录:chdir (); . chroot() 进程的资源:
LESSOPEN=|/usr/bin/lesspipe.sh %s HISTSIZE=1000 HOSTNAME= LOGNAME=liuzm REMOTEHOST=162.105.204.163 MAIL=/usr/spool/mail/liuzm TERM=ansi HOSTTYPE=i386 PATH=/usr/local/bin:/bin:/usr/bin:/usr/ X11R6/bin:/home/liuzm/bin:. HOME=/home/liuzm INPUTRC=/etc/inputrc SHELL=/bin/bash USER=liuzm LANG=en_US OSTYPE=Linux SHLVL=1 LS_COLORS= _=./a.out
相关文档
最新文档