操作系统课程设计(三)-Linux进程间通信
写在前面
又到了 一年一度期末课设的时候,距离考试还有12天的时间,此时胡小宁还没有复习(准确的说是学习)之前的课程,所以在这个平平无奇的周二,胡小宁就要开始做课设了!
实验三 Linux 进程间通信
实验目的
Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,通过本实验,理解熟悉 Linux 支持的消息通信机制。
实验内容和步骤
(1)使用系统调用 msgget(),msgsnd(),msgrcv()及 msgctl()编制一长度为 1K 的消息的发送和接收程序。
- 为了便于操作和观察结果,用一个程序作为“引子”,先后 fork()两个子进程 SERVER和 CLIENT,进行通信。
- SERVER 端建立一个 key 为 75 的消息队列,等待其他进程发来的消息。当遇到类型为 1 的消息,则作为结束信号,取消该队列,并退出 SERVER。SERVER 每接收到一个消息后显示一句“(server) received”。
- CLIENT 端使用 key 为 75 的消息队列,先后发送类型从 10 到 1 的消息,然后退出。最后的一个消息,即是 SERVER 端需要的结束信号。CLIENT 每发送一条消息后显示一句“(client)sent”。
- 父进程在 SERVER 和 CLIENT 均退出后结束。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75
struct msgform
{
long mtype;
char mtext[1030];
}msg;
int msgqid,i;
void CLIENT()
{
int i;
msgqid=msgget(MSGKEY,0777);
for (i=10;i>=1;i--)
{
msg.mtype=i;
printf("(client) sent \n");
msgsnd(msgqid,&msg,1024,0);
}
exit(0);
}
void SERVER()
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);
do{
msgrcv(msgqid,&msg,1030,0,0);
printf("(Server) recieved\n");
} while(msg.mtype!=1);
msgctl(msgqid,IPC_RMID,0);
exit(0);
}
void main()
{
while((i=fork())==-1);
if(!i) SERVER();
while((i=fork())==-1);
if(!i) CLIENT();
wait(0);
wait(0);
}运行效果如下:
UINX/Linux 系统把信号量、消息队列和共享资源统称为进程间通信资源(IPC resource)。提供给用户的 IPC 资源是通过一组系统调用实现的。
用信号量对进程要访问的临界资源进行保护。
用消息队列在进程间以异步方式发送消息。
用一块预留出的内存区域供进程之间交换数据。
分析:
创建 IPC 资源的系统调用有:
semget()—获得信号量的 IPC 标识符。
msgget()—获得消息队列的 IPC 标识符。
shmget()—获得共享内存的 IPC 标识符。
控制 IPC 资源的系统调用有:
semctl()—对信号量资源进行控制的函数。
msgctl()—对消息队列进行控制的函数。
shmctl()—对共享内存进行控制的函数。
上述函数为获得和设置资源的状态信息提供了一些命令。例如:
IPC_SET 命令:设置属主的用户标识符和组标识符。
IPC_STAT 和 IPC_INFO 命令:获得资源状态信息。
IPC_RMID 命令:释放这个资源。
操作 IPC 资源的系统调用有:
semop()—获得或释放一个 IPC 信号量。 可以实现 P、V 操作
msgsnd()—发送一个 IPC 消息。
msgrcv()—接收一个 IPC 消息。
shmat()—将一个 IPC 共享内存段添加到进程的地址空间
shmdt()——将 IPC 共享内存段从私有的地址空间剥离。
message的传送和控制并不保证完全同步,当一个程序不在激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理。
(2)观察参考程序,说明控制消息队列系统调用 msgctl()在此起什么作用?
在此调用msgctl是用于删除id的消息队列。