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中ipc机制

linux中ipc机制
Linux IPC(Inter-Process Communication)机制
1、什么是IPC
Inter-Process Communication,即进程间通信,是操作系统中提供的一种机制,它允许多个进程在没有同时运行的情况下,能够进行通信、协作和共享数据。
Linux提供了五种IPC机制:信号量、管道、消息队列、共享内存、Socket。
2、信号量
信号量是用于同步的一种技术,它主要用于解决两个以上进程同时访问同一资源的问题,即资源竞争问题。
信号量是一个计数锁,可以用它来保护共享资源,它可以阻止多个进程同时进入临界区,以保护临界资源。
3、管道(pipe)
管道的创建是由内核完成的,管道是一种半双工的通信方式,它具有一端数据输入,另一端负责数据输出。
管道只能用于具有公共祖先的两个进程之间的通信。
4、消息队列
消息队列是一种异步的IPC机制,它允许多个进程之间在内核中传递消息。
消息队列在缓存中存储消息,如果消息队列满了,则写入消息失败,如果消息队列空了,则读取消息失败。
5、共享内存
共享内存是一种实时的IPC机制,它比消息队列的通信速度快得
多,因为它不需要内核处理。
共享内存可用于多个进程之间的共享数据,这样多个进程可以访问该共享内存区域的数据,从而减少数据传输时间。
6、 Socket
Socket是一种进程间通信技术,它允许两个或多个进程之间通过网络进行通信。
Socket也可以用作本地进程间的通信,它在多个不同的操作系统中可以使用,甚至可以在不同操作系统之间通信。
linux线程间通信方式

linux线程间通信方式
Linux 线程间通信方式包括以下几种:
1. 管道通信:管道是一种半双工的通信方式,只能用于具有亲缘关系的进程之间的通信,父进程创建管道,在进程间传递数据。
2. 信号通信:信号是一种异步通信方式,在进程之间传递简单的信息。
一个进程向另一个进程发送一个信号,另一个进程收到信号后就可以采取相应的操作。
3. 共享内存通信:共享内存是最快的进程间通信方式,可以将内存区域映射到多个进程的地址空间中,实现进程间数据的共享。
需要注意解决信号量、锁等同步问题。
4. 信号量通信:信号量是一种计数器,用来协调多个进程对共享资源的访问。
多个进程需要对信号量进行操作,以实现对共享资源的访问控制。
5. 消息队列通信:消息队列是一种通过消息传递来进行通信的机制,可以在进程之间传递数据块,通常用于进程间的同步和异步通信。
6. 套接字通信:套接字是基于网络通信的一种进程间通信方式,可用于同一主机上进程间通信,也可以在不同主机之间通信。
套接字是基于 TCP/IP 协议栈实现的,需要在数据传输时注意网络传输和数据结构转换等问题。
以上是 Linux 线程间通信的主要方式,开发者可以根据不同的需求和场景选择合适的方式。
linux 下进程间通过信号进行通信的具体实现过程

linux 下进程间通过信号进行通信的具体实现过程嘿,朋友!咱们今天来聊聊 Linux 下进程间通过信号进行通信的那些事儿。
你想啊,在 Linux 的世界里,进程就像是一个个忙碌的小精灵,各自忙着自己的任务。
那它们之间要交流咋办?这时候信号就派上用场啦!比如说,一个进程就像是一个正在专心做饭的大厨,另一个进程就像是旁边等着上菜的服务员。
大厨做好一道菜,给服务员一个“上菜”的信号,这就是进程间通过信号交流的简单类比。
那具体咋实现呢?首先,得知道有哪些常见的信号。
就像不同的菜品有不同的名字一样,信号也有它自己的名字和编号。
比如说,SIGINT 表示中断信号,SIGTERM 表示终止信号。
然后呢,一个进程要给另一个进程发信号,就像大厨把做好的菜递给服务员一样,得有个传递的方法。
这时候就用到了系统提供的函数,比如 kill 函数。
咱们再深入一点,发信号的时候还得注意一些细节。
比如说,得有权限吧?不能随便一个进程都能给别的进程乱发信号,那不乱套啦?接收信号的进程也得做好准备,就像服务员得时刻准备接大厨递过来的菜一样。
它得注册信号处理函数,告诉系统收到特定信号该咋处理。
这处理方式也有讲究,是直接忽略这个信号,还是采取一些特定的动作?比如说暂停一下,或者干脆结束自己。
你说,这是不是跟我们生活中人与人之间的交流有点像?总得有个方式传递信息,还得知道收到信息后该咋办。
总之,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

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进程间通讯的几种方式的特点和优缺点Linux进程间通讯的方式有多种,其优缺点也不尽相同,接受者依赖发送者之时间特性可承载其优端。
下面就讨论几种典型的方式:1、管道(Pipe):是比较传统的方式,管道允许信息在不同进程之间传送,由一端输入,另一端输出,提供全双工式劝劝信息传送,除此之外,伺服端也可以将其服务转换为管道,例如说Web服务程序。
管道的优点:简单易懂、可靠、灵活、容易管理,可以控制发送端和接收端的信息流量。
管道的缺点:线程之间的信息量不能太大,也只能在本机上使用,不能通过网络发送信息。
2、消息队列(Message queue):消息队列主要应用在大型网络中,支持多种消息队列协议,广泛用于在远程机器上的进程间的交互、管理进程间的数据和同步问题。
消息队列的优点:主要优点是这种方式可以将消息发送给接收端,然后接收端可以从距离发送端远的地方网络上接收消息,通过消息队列可以较好的管理和控制进程间的数据流量和同步问题。
消息队列的缺点:缺点是消息队里的管理复杂,并且有一定的延迟,而且它使用时应避免共享内存,对于多处理器和跨网络环境, TCP 传输数据时也比不上消息队列的传输效率高。
3、共享内存(Share Memory):是最高效的进程间通信方式,也是最常用的,它使进程在通信时共享一个存储地址,双方都可以以该存储地址作为参数进行读写操作。
共享内存的优点:实现高性能,数据同步操作快、数据可以高速传输,可以解决多处理器以及跨网络环境的通信。
共享内存的缺点:由于进程间直接使用物理内存,没有任何保护,所需要使用较复杂的同步机制来完成数据的可靠传输。
总的来说,每种进程通讯方式都有各自的优缺点,不同的系统需求也许需要多种方案的相互配合才能有效的处理系统间通信的问题。
系统设计者应根据具体系统需求,选择合适的进程通信方式来实现更好的进程间通信。
简述linux中进程间各种通信方式特点

简述linux中进程间各种通信方式特点Linux中进程间通信方式有多种,包括管道,命名管道,消息队列,信号量,共享内存和套接字。
每种通信方式都有自己的特点和适用场景。
一、管道1. 特点:- 管道是最简单的进程间通信方式之一,只能用于具有父子关系的进程间通信。
- 管道是一个单向通道,数据只能在一个方向上流动。
- 管道的容量有限,在写度满之前,读进程阻塞;在读度空之前,写进程阻塞。
2. 使用场景:- 父子进程之间需要进行简单的数据传输。
二、命名管道1. 特点:- 命名管道是一种特殊类型的文件,可以实现不相关进程的通信。
- 命名管道是半双工的,只能在一个方向上传输数据。
- 命名管道是顺序读写的,进程可以按照顺序读取其中的数据。
2. 使用场景:- 不相关的进程需要进行数据传输。
- 需要按照顺序进行传输的场景。
三、消息队列1. 特点:- 消息队列是一组消息的链表,具有特定的格式和标识符。
- 消息队列独立于发送和接收进程的生命周期,可以实现不相关进程间的通信。
- 消息队列可以根据优先级进行消息的传输。
2. 使用场景:- 需要实现进程间相对复杂的数据传输。
- 数据传输具有优先级。
四、信号量1. 特点:- 信号量是一个计数器,用于实现多个进程之间的互斥和同步。
- 信号量有一个整数值,只能通过定义的操作进行访问。
- 信号量可以用于控制临界区的访问次数。
2. 使用场景:- 多个进程需要共享公共资源。
- 需要进行互斥和同步操作。
五、共享内存1. 特点:- 共享内存是一块可以被多个进程共同访问的内存区域。
- 共享内存是最快的进程间通信方式,因为数据不需要在进程之间拷贝。
- 共享内存需要通过同步机制(如信号量)进行互斥访问。
2. 使用场景:- 需要高效地进行大量数据传输。
- 数据读写频繁,需要最小化数据拷贝的开销。
六、套接字1. 特点:- 套接字是一种网络编程中常用的进程间通信方式。
- 套接字支持不同主机上的进程进行通信。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
linux进程间通讯
管道(FIFO):
管道可分为命名管道和非命名管道(匿名管道),匿名管道只能用于父、子进程间通讯,命名管道可用于非父子进程。
命名管道就是FIFO,管道是先进先出的通讯方式。
消息队列:
消息队列用于2个进程间通讯,首先在1个进程中创建1个消息队列,然后可向消息队列中写数据,而另一进程可从该消息队列中读取数据。
注意,消息队列是以创建文件的方式建立的,若1个进程向某消息队列中写入数据后,另一进程并未读取这些数据,则即使向消息队列中写数据的进程已退出,但保存在消息队列中的数据并未消失,也就是说下次再从这个消息队列中读数据时,还是会读出已退出进程所写入的数据。
信号量:
linux中的信号量类似于windows中的信号量。
共享内存:
共享内存,类似于windows中dll的共享变量,但linux下的共享内存区不需要象DLL这样的东西,只要先创建1个共享内存区,其它进程按照一定步骤就能访问到这个共享内存区中的数据(可读可写)。
信号——signal
套接字——socket
各种ipc机制比较:
1.匿名管道:速度较慢,容量有限,且只有父、子进程间能通讯;
2.命名管道(FIFO):任何进程间都能通讯,但速度较慢;
3.消息队列:容量受系统限制,且要对读出的消息进行测试(读出的是新写入的消息,还是以前写入的,
尚未被读取的消息);
4.信号量:不能传递复杂信息,只能用来同步;
5.共享内存:容量大小可控,速度快,但共享内存区不包含同步保护,对共享内存区的访问需由用户实
现同步保护。
另外,共享内存同样可用于线程间通讯,不过没必要,线程间本来就已共享了同一进程内的一块内存。
线程间同步方法:
1.临界区:使多线程间串行访问公共资源或1段代码,速度较快,适合控制数据访问;
2.互斥量:为同步对共享资源的单独访问而设计的;
3.信号量:为控制1个具有有限数量用户资源而设计;
4.事件对象:用来通知线程有一些事件已发生,从而启动后继任务。
1.事件对象(Event):
用事件(Event)来同步线程是最具弹性的。
1个事件有2种状态:激发态和未激发态,也称为信号态和无信号态。
事件又分2种类型:手动重置事件和自动重置事件。
手动重置事件被设置为激发态后,会唤醒所有等待的线程,且一直保持为激发状态,直到程序重新把它设置为未激发状态. 自动重置事件被设置为激发态后,会唤醒“1个”等待中的线程,然后自动恢复为未激发状态. 所以用自动重置事件来同步2个线程比较理想。
2、临界区(Critical Section):
使用临界区的第1个忠告就是不要长时间锁住1个资源,进入临界区后必须尽快离开,并释放资源。
临界区的1个缺点就是:Critical Section不是1个核心对象,无法获知进入临界区的线程是生是死,若线程在临界区中崩溃,没有释放临界资源,系统无法获知,且没有办法释放该临界资源。
这个缺点在互斥体(Mutex)中得到了弥补。
3、互斥体(Mutex):
互斥体的功能和临界区类似。
区别是:Mutex所花费的时间比Critical Section多,但Mutex是核心对象(Event、Semaphore也是),可以跨进程使用,且等待1个被锁住的Mutex可以设定TIMEOUT,不会像Critical Section那样无法得知临界区域的情况,而一直死等。
4、信号量(Semaphore):
信号量是最具历史的同步机制,信号量是解决producer/consumer(生产者/消费者)问题的关键要素。
线程通信:
1.全局变量:
进程中的线程间共享内存,这是比较常用的通信方式和交互方式。
注:全局变量最好使用volatile来修饰,以防编译器对变量进行优化。
2.Message消息机制:
常用的Message通信接口主要有2个:PostMessage()和PostThreadMessage():
●PostMessage()为线程向主窗口发送消息;
●PostThreadMessage()是任意2个线程间的通信接口。
3.事件对象——CEvent对象
同步与互斥比较:
同步,是指不同进程中的若干代码段,它们必须按照规定顺序来运行,这种先后次序依赖于要完成的特定任务。
互斥,是指不同进程中的若干代码段,当某进程运行其中1个代码段时,其它进程就不能运行它们之中的任一代码段,只能等到该进程退出这个代码段后才可以运行。
死锁:
产生死锁的原因:
1.竞争资源;
2.进程推进顺序不当。
产生死锁的必要条件:
1.互斥条件:1个资源在一段时间内只能被1个进程所使用,具有排它性;
2.请求和保持:1个进程在请求新资源而阻塞时,对已获得资源又保持不放;
3.不剥夺:内核无法剥夺进程已获得的资源,只能由进程自己释放;
4.环路等待:在发生死锁时,必然存在1个进程-资源的环形链,即进程集合{P1,P2,...,Pn}中
的P1正在等待P2占用的资源,P2正在等待P3占用的资源,...,Pn正在等待P1占用的资源
(ABBA型死锁)。