Linux进程间通信

合集下载

实验十八--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机制
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线程间通信方式
Linux 线程间通信方式包括以下几种:
1. 管道通信:管道是一种半双工的通信方式,只能用于具有亲缘关系的进程之间的通信,父进程创建管道,在进程间传递数据。

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

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

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

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

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

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

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

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

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

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

linux 下进程间通过信号进行通信的具体实现过程

linux 下进程间通过信号进行通信的具体实现过程

linux 下进程间通过信号进行通信的具体实现过程嘿,朋友!咱们今天来聊聊 Linux 下进程间通过信号进行通信的那些事儿。

你想啊,在 Linux 的世界里,进程就像是一个个忙碌的小精灵,各自忙着自己的任务。

那它们之间要交流咋办?这时候信号就派上用场啦!比如说,一个进程就像是一个正在专心做饭的大厨,另一个进程就像是旁边等着上菜的服务员。

大厨做好一道菜,给服务员一个“上菜”的信号,这就是进程间通过信号交流的简单类比。

那具体咋实现呢?首先,得知道有哪些常见的信号。

就像不同的菜品有不同的名字一样,信号也有它自己的名字和编号。

比如说,SIGINT 表示中断信号,SIGTERM 表示终止信号。

然后呢,一个进程要给另一个进程发信号,就像大厨把做好的菜递给服务员一样,得有个传递的方法。

这时候就用到了系统提供的函数,比如 kill 函数。

咱们再深入一点,发信号的时候还得注意一些细节。

比如说,得有权限吧?不能随便一个进程都能给别的进程乱发信号,那不乱套啦?接收信号的进程也得做好准备,就像服务员得时刻准备接大厨递过来的菜一样。

它得注册信号处理函数,告诉系统收到特定信号该咋处理。

这处理方式也有讲究,是直接忽略这个信号,还是采取一些特定的动作?比如说暂停一下,或者干脆结束自己。

你说,这是不是跟我们生活中人与人之间的交流有点像?总得有个方式传递信息,还得知道收到信息后该咋办。

总之,Linux 下进程间通过信号通信,就像是一个有条不紊的小社会,每个进程都遵循着一定的规则和方式进行交流,以保证整个系统的稳定和高效运行。

所以啊,只要咱们搞清楚这些规则和方法,就能在 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进程间通讯的几种方式的特点和优缺点

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

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

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

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

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

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

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

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

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

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

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

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

简述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)。

如何指定信号处理方式?
表 7-16 所需头文件 函数原型 #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) signum:信号代码,可以为除 SIGKILL 及 SIGSTOP 外的任何一个特定有效的信号 Act:指向 struct sigaction struct sigaction { void (*sa_handler)(int signo); sigset_t sa_mask; int sa_flags; void (*sa_restore)(void); } Oldact:指向 struct sigaction 函数返回值 0 表示成功, -1 表示有错误发生 siga ct ion ( ) 函数语法要点
void main() { printf("Waiting for signal SIGINT or SIGQUIT...\n"); signal(SIGINT, my_func); //收到信号SIGINT,转去执行函数my_func for(;;); exit(0); }
例2:子进程等收到信号才结束
if (pid == 0) {/*子进程*/ printf("Child(pid : %d) is waiting for any signal\n", getpid()); raise(SIGSTOP);// 使子进程暂停 exit(0); }
else {/*父进程*/ if ((waitpid(pid, NULL, WNOHANG)) == 0) { if ((ret = kill(pid, SIGKILL)) == 0) //向子进程发结束信号 printf("Parent kill %d\n",pid); } waitpid(pid, NULL, 0); exit(0); }
Linux进程间通信
Hale Waihona Puke 管道 怎么知道有哪些信号 怎么产生信号 收到信号后怎么处理
怎么知道有哪些信号
查看信号:
kill -l
常用信号
表 7-14 信 号 名 常见信号的含义及其默认操作 含 义 默 认 操 作 终止 终止 终止 终止 终止 终止 终止 暂停进程 停止进程 忽略
SIGHUP SIGINT SIGQUIT SIGILL SIGFPE SIGKILL SIGALRM SIGSTOP SIGTSTP SIGCHLD SIGABORT
如何指定信号处理方式?
表 7-15 所需头文件 函数原型 sign a l( ) 函数语法要点 #include <signal.h> void (*signal(int signum, void (*handler)(int)))(int) signum:指定信号代码 函数传入值 handler: SIG_IGN:忽略该信号 SIG_DFL:采用系统默认方式处理信号 自定义的信号处理函数指针 成功:以前的信号处理配置 函数返回值 出错:1
收到信号后:以下之一处理
• 第一,如果指定了一个信号处理函数,收到信号 后,就转去执行这个信号处理函数。 • 第二,每个信号都有一个默认处理方式(用 SIG_DFL表示 • 第三,忽略这个信号(用SIG_IGN表示)。
signal(SIGINT ,fun ); signal(SIGINT ,SIG_DFL );//可以不写的 signal(SIGINT ,SIG_IGN );
该信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控 制进程结束时,通知同一会话内的各个作业与控制终端不再关联 该信号在用户键入 INTR 字符(通常是 Ctrl-C)时发出,终端驱动程序发送此 信号并送到前台进程中的每一个进程 该信号和 SIGINT 类似,但由 QUIT 字符(通常是 Ctrl-\)来控制 该信号在一个进程企图执行一条非法指令时(可执行文件本身出现错误, 或者试图执行数据段、堆栈溢出时)发出 该信号在发生致命的算术运算错误时发出。这里不仅包括浮点运算错误, 还包括溢出及除数为 0 等其他所有的算术错误 该信号用来立即结束程序的运行,并且不能被阻塞、处理或忽略 该信号当一个定时器到时的时候发出 该信号用于暂停一个进程,且不能被阻塞、处理或忽略 该信号用于交互停止进程,用户键入 SUSP 字符时(通常是 Ctrl+Z)发出 这个信号 子进程改变状态时,父进程会收到这个信号 进程异常终止时发出
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t pid; int ret; /* 创建一子进程 */ if ((pid = fork()) < 0) { printf("Fork error\n"); exit(1);}
总结
• 当收到信号后,才可以开始某段程序的执行!所 以又称为软中断
Linux进程间通信
管道
怎么知道有哪些信号 怎么产生信号 收到信号后怎么处理
怎么产生信号?
• 敲某个键盘(组合) SIGINT • 某个进程结束 SIGCHLD • 有些函数可以发信号: kill()、raise()、alarm()
Linux进程间通信
管道
怎么知道有哪些信号 怎么产生信号 收到信号后怎么处理
函数传入值
Linux进程间通信
管道
怎么知道有哪些信号 怎么产生信号 收到信号后怎么处理 举例
例1:敲下ctrl+c,就输出:I have get SIGINT
#include <signal.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> /*信号处理函数*/ void my_func(int sign_no) { if (sign_no == SIGINT) printf("I have get SIGINT\n"); }
Linux进程间通信
• 传统进程通信
• 信号通信 • 管道通信 • 消息队列 • 共享主存 • 信号量
• System V IPC进程通信
• Socket网络进程通信
信号
• 信号是一个发送到进程的特殊信息,是一个整数 值。不同的值代表着不同的意义。Linux在signal.h 文件中定义了常量标识来代表这些信号,方便编 程者引用
相关文档
最新文档