一、实验目的
理解并熟悉Linux支持的消息通信机制。
二、实验内容
1、实验原理
Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据。
2、运用的理论知识及算法
(1)msgget()函数:获得消息队列的 IPC 标识符
(2)msgsnd()函数:发送一个 IPC 消息
(3)msgrcv()函数:接收一个 IPC 消息
(4)msgctl()函数:对消息队列进行控制的函数
3、程序流程图
4、步骤和方法
(1)fork()两个子进程SERVER和CLIENT进行通信;
(2)SERVER端建立一个key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,作为结束信号取消该队列并退出SERVER。SERVER每接收到一个消息后显示“(server) received”;CLIENT端使用一个key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息即是SERVER端需要的结束信号。CLIENT每发送一条消息后显示“(client) sent”;
(3)父进程在SERVER和CLIENT均退出后结束。
5、关键代码
void CLIENT() { msgqid=msgget(MSGKEY,0777); for (int 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);
}
三、实验结果与分析
1、实验结果
分析:这里多数情况如左图一样是所有client发出信息后,server再接受信息,而右图是一种少数情况(即client发出一条后server接受一条)。原因是message的传送和控制并不保证完全同步。当一个程序未处于激活状态的时候,它可能会继续睡眠,从而造成出现的多数情况。
2、问题解决
说明控制消息队列系统调用msgctl()在此起什么作用?
msgctl()在此起读取消息队列状态信息并修改的作用。
四、小结与心得体会
通过对Linux进程间控制实验的学习,理解了进程间通信的基本原理,此实验初始情况下消息队列为空,因此server进程被强制阻塞,当client进程发出信号后,可唤醒阻塞的server进程,共同抢占处理器资源,同理消息队列为满时,client进程被强制阻塞,此时只允许server进程接收信号。通过进程之间的通信,实现了进程的同步。同时也学到了更多的函数调用。