linux进程间通信

合集下载

列举出 linux 系统中常用的进程通信机制,并对每种机制进行简单说明。

列举出 linux 系统中常用的进程通信机制,并对每种机制进行简单说明。

列举出 linux 系统中常用的进程通信机制,并对每种机制进行简单说明。

一、管道(Pipe)管道是最基本的进程间通信(IPC)机制之一,通常用于父子进程或对称多处理中的进程间通信。

它是一种命名管道,通过文件系统中的特殊文件实现。

使用管道,一个进程可以将数据发送到另一个进程,从而实现进程间的通信。

使用方法:1. pipe() 函数创建管道并将文件描述符返回给调用进程。

2. write() 函数从文件描述符向管道写入数据。

3. read() 函数从管道读取数据。

二、信号(Signal)信号是一种简单的进程间通信机制,用于通知接收进程某个事件的发生。

信号可以由系统生成(如操作系统的调度),也可以由其他进程发送。

信号通常用于通知接收进程发生错误、终止或需要执行某些操作。

使用方法:1. 发送信号:kill() 或 raise() 函数发送信号。

2. 接收信号:处理信号的函数(如信号处理程序)需要注册到进程中。

三、消息队列(Message Queue)消息队列是一种更为复杂的进程间通信机制,它允许不同进程之间发送和接收消息。

消息队列提供了一种高效、可靠的消息传递机制,适合于分布式系统中的进程间通信。

使用方法:1. mq_open() 函数创建或打开消息队列,并返回一个消息队列标识符。

2. mq_send() 和 mq_receive() 函数分别用于发送和接收消息。

四、共享内存(Shared Memory)共享内存是一种轻量级的进程间通信机制,允许多个进程共享同一块内存区域。

它适用于需要快速数据交换的进程间通信场景,如多线程或分布式系统中的进程间通信。

使用方法:1. mmap() 函数将一段虚拟地址空间映射到进程的地址空间中,实现进程间的共享内存。

2. 读写共享内存区域进行数据交换。

五、套接字(Socket)套接字是一种更为灵活的进程间通信机制,它提供了更为广泛的网络通信功能。

套接字可以是基于网络的,也可以是本地进程间的通信机制。

实验十八--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,该路径可以随便设置。

linux dbus协议标准

linux dbus协议标准
DBus(D-Bus)是Linux系统下的一种进程间通信协议,它允许应用程序在系统级别进行通信。

DBus协议是一种基于消息传递的协议,类似于Unix中的Unix Domain Sockets。

DBus协议定义了一组标准的消息格式和消息传递规则,以确保不同应用程序之间的通信能够正常进行。

DBus协议标准包括以下几个方面:
1. 消息格式:DBus消息由一系列字节组成,其中包括消息类型、消息ID、目标地址、数据长度和数据内容等信息。

DBus消息分为三种类型:消息、方法调用和方法响应。

2. 消息传递规则:DBus协议规定了消息传递的规则,包括消息的发送和接收顺序、消息的传递方式、消息的传递超时时间等。

DBus协议还规定了一些特殊情况下的消息传递规则,如消息的重复发送和接收等。

3. 地址和对象路径:DBus协议中的消息是通过地址和对象路径来指
定目标应用程序或对象的。

DBus地址分为两种类型:名称和ID。

DBus 对象路径是指应用程序或对象在系统中的路径,通常由多个部分组成。

4. 认证和授权:DBus协议中的应用程序可以通过认证和授权机制来保护通信的安全性。

DBus协议提供了一些认证和授权机制,如基于密码的认证和基于权限的授权等。

5. 错误处理:DBus协议中的应用程序可以通过错误处理机制来处理通信中的错误。

DBus协议提供了一些错误处理机制,如消息丢失和消息重复等。

总之,DBus协议是Linux系统下的一种重要的进程间通信协议,它定义了一组标准的消息格式和消息传递规则,以确保不同应用程序之间的通信能够正常进行。

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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
分析:为了清楚看到结果,主程序等待 2 秒后打印输出一条语句,共打印输 出 5 条语句;要使用户按下中断键跳到自定义函数,还是用比较简单的 signal 函 数,用户按 Ctrl+C 键不能影响正在运行的程序,就需要阻塞中断信号,用 sigemptyset、sigaddset 和 sigprocmask 三个函数。在程序主体运行完毕后,用 sigprocmask 函数解除中断信号的阻塞,转入自定义函数运行。
(void) signal(SIGINT,SIG_DFL);
/*重新恢复 SIGINT 信号的系统默认处理*/
}
步骤 1 编辑源程序代码。 步骤 2 用 gcc 编译程序。 [root@localhost root]#gcc 7-5.c -o 7-5 步骤 3 运行程序。 编译成功后,运行可执行文件 7-5,输入“./7-5”,此时系统会出现运行结果, 等待 2 秒打印输出一段相同的文字,共打印输出 5 条。 如果在打印输出文字的时候,用户没有按下 Ctrl+C 键,程序在打印输出完 5 条信息后结束运行。 如果在打印输出文字的时候,用户按下 Ctrl+C 键。程序没有马上进入信号处 理程序,而是仍然打印输出文字,等到打印输出完毕,程序才进入自定义信号处 理函数。
(void) signal(SIGINT,fun_ctrl_c); /*调用 fun_ctrl_c 函数*/
if(sigemptyset(&set)<0)
/*初始化信号集合*/
perror("初始化信号集合错误");
if(sigaddset(&set,SIGINT)<0)
/*把 SIGINT 信号加入信号集合*/
一个完整的信号生命周期从信号发送开始,结束于相应的处理函数执行完毕。 整个生命周期分为信号诞生、信号在进程中注册、信号在进程中注销和信号处理函 数执行完毕。
【例 7.5】设计一个程序,要求主程序运行时,即使用户按下中断键(Ctrl+C), 也不能影响正在运行的程序,即让信号处于阻塞状态,当主体程序运行完毕后才 进入自定义信号处理函数。
【例 7.7】设计一个程序,要求创建一个管道,复制进程,父进程往管道中 写入字符串,子进程从管道中读取并输出字符串。
分析 主程序调用 pipe 函数创建一个管道,调用 fork 函数创建进程; 父进程中先用 close(pipe_fd[0])关闭 pipe_fd[0],剩下的 pipe_fd[1]用来把数据
上机四:Linux 进程间通信
1. 目的
(1).理解信号和管道的概念及实现进程间通信的原理。 (2).掌握信号通信机制,学会通过信号实现进程间通信。 (3).掌握管道及命名管道通信机制,学会通过管道实现进程间通信。 (4). 掌握和使用消息队列实现进程间通信。 (5). 掌握和使用共亨主存实现进程间通信。 (6).了解和使用信号量实现进程同步。
int pipe_fd[2];
char buf_r[100],buf_w[100];
memset(buf_r,0,sizeof(buf_r)); /*把 buf_r 所指的内存区域的前 sizeof(buf_r)得到的字节置为 0,初始化清空的操作*/
if(pipe(pipe_fd)<0)
/*调用 pipe 函数,创建一个管道*/
perror("加入信号集合错误");
2
if(sigprocmask(SIG_BLOCK,&set,NULL)<0)/*把信号集合加入到当前进程的阻塞集合中 */
perror("往信号阻塞集增加一个信号集合错误"); else {
for(i=0;i<5;i++) {
printf("显示此文字,表示程序处于阻塞信号状态!\n"); sleep(2); } } if(sigprocmask(SIG_UNBLOCK,&set,NULL)<0)/*当前的阻塞集中删除一个信号集合*/
exit(0) ;
}
else if (result==0)
/*子进程运行代码段*/
{
close(pipe_fd[1]);
if((r_num=read(pipe_fd[0],buf_r,100))>0)
printf("子进程从管道读取%d 个字符,读取的字符串是:%s\n",r_num,buf_r);
4
写入管道,利用 write 函数写入字符串,然后用 close(pipe_fd[1])关闭 pipe_fd[1]; 子进程是用 close(pipe_fd[1])关闭 pipe_fd[1],剩下的 pipe_fd[0]用来从管道读
取数据,利用 read 函数读取字符串,然后用 close(pipe_fd[0])关闭 pipe_fd[0]。
printf("父进程向管道写入:%s\n",buf_w);
5
close(pipe_fd[1]); waitpid(result,NULL,0);//调用 waitpid, 阻塞父进程,等待子进程退出 exit(0); } }
步骤 1 编辑源程序代码。 [root@localhost root]#vi 7-7.c 步骤 2 用 gcc 编译程序。 [root@localhost root]#gcc 7-7.c -o 7-7 步骤 3 运行程序。 [root@localhost root]#./7-7 请从键盘输入写入管道的字符串 aabbbcccc 父进程向管道写入:aabbbcccc 子进程从管道读取 9 个字符,读取的字符串是:aabbbcccc
#include<sys/wait.h>
/*文件预处理,包含 waitpid 函数库*/
#include<unistd.h>
/*文件预处理,包含进程控制函数库*/
#include<string.h>
int main ()
/*C 程序的主函数,开始入口*/
{
先出”形式的文件存在于文件系统中。因此,只要可以访 问该文件路径,就能够彼此通过命名管道相互通信。为实现多进程间基于命名管道 的通信,首先使用 mkfifo()创建一个命名管道。随后可使用—般的文件 I/O 函数, 如 open()、close()、read()、write()等,来对它进行操作,从而实现多进程间的通信。
close(pipe_fd[0]);
exit(0);
}
else
/*父进程运行代码段*/
{
close(pipe_fd[0]);
printf("请从键盘输入写入管道的字符串\n");
scanf("%s",buf_w);
if(write(pipe_fd[1],buf_w,strlen(buf_w))!=-1)
#include<sys/types.h>
/*文件预处理,包含进程控制函数库*/
#include<unistd.h>
/*文件预处理,包含进程控制函数库*/
void fun_ctrl_c();
/*自定义信号处理函数声明*/
/*C 程序的主函数,开始入口*/ int main () {
int i; sigset_t set,pendset; struct sigaction action;
7-5.c 7-7.c 7-8zhang.c 7-8li.c 7-10.c 7-12write.c 7-12read.c
3. 步骤
3.1. 信号通信 信号是一种简洁的通信方式,进程或内核均可使用信号通知一个进程有
某种 事件发生。信号全称为软中断信号,也称作软中断,它实质上是在软件层
1
次上对中断机制的一种模拟,一个进程收到一个信号与 CPU收到一个中断请 求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,用来通知 进程有异步事件发生。进程之间可以通过函数,如kill()和alarm()等传递软中 断信号。内核也可在发生内部事件时向进程发送信号,通知进程发生了某个事 件。信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。
非阻塞型通信情形下父子进程共存,当产生相关信号,如SIGINT时,父 子进程都能接收到此信号,只是先由父进程响应,再由父进程把此信号传递给 子进程。但需要注意,如果父进程没有对该信号的自定义处理,则父子进程都 接受信号的默认处理。
3.2. 管道通信 管道技术是 Linux 操作系统中由来已久的一种进程间通信机制,分为匿名管
3.3. 命名管道
匿名管道技术可以用于连接具有共同祖先的进程,例如父子进程间的通信, 但它无法实现不同用户的进程间的信息共享。匿名管道不能常设,当访问管道的进 程终止时,管道需要撤销。这些限制给匿名管道的使用带来不少限制,命名管道克 服了这些限制。
命名管道也称为 FIFO,是一种永久性的机构。FIFO 文件也具有文件名、文 件长度、访问许可权等属性,以 FIFO 的文件形式存在于文件系统中。它可以像其 它 Linux 文件那样被打开、关闭和删除,所以任何进程都通过路径找到它。进程间 彼此能够通过 FIFO 相互通信(能够访问该路径的进程以及 FIFO 的创建进程之间), 因此,通过 FIFO 不相关的进程也能交换数据。值得注意的是,FIFO 严格遵循“先 进先出”原则,对匿名管道及命名管道的读总是从开始处返回数据,对它们的写则 把数据添加到末尾。一般文件的 I/O 函数都可以用于命名管道,如 close()、read() 和 write()等。
2. 内容
进程间通信机制可以主要两类:传统的进程间通信(包括信号、管道、命名 管道)和 System V 的进程间通信(包括消息队列、信号量、共享主存)。
a)根据实验原理描述的背景,编写基于 C 语言的程序。 b)在 Linux 操作系统中编译、运行、调试程序,并观察分析实验结果。 主要上机分析代码文件。
相关文档
最新文档