操作系统——实验三(进程间通信)——3.3.3

操作系统——实验三(进程间通信)——3.3.3

实验目的

1、了解linux系统中进程通信的基本原理。

2、分析进程竞争资源现象,学习解决进程互斥的方法。


3.3.3消息通信

使用系统调用msgget(),msgsnd(),msgrcv()及msgctl()编制一长度为1K的消息发送和接收的程序。

〈程序设计〉

(1)为了便于操作和观察结果,用一个程序为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。

(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。SERVER每接收到一个消息后显示一句“(server)received”。

(3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。

(4)父进程在SERVER和CLIENT均退出后结束。

第一步

创建c文件夹,在它下面创建test.c文件

mkdir c
vim test.c

第二步

写入参考程序

程序

#include
#include
#include
#include
#define MSGKEY 75/*定义关键词MEGKEY*/
struct msgform/*消息结构*/
{
long mtype;
char mtxt[1030];/*文本长度*/
}msg;
int msgqid,i;

void CLIENT()
{
int i;
msgqid=msgget(MSGKEY,0777);
for(i=20;i>=1;i--)
{
msg.mtype=i;
printf("(client)sent\n");
msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/
}
exit(0);
"c/test3.c" 45L, 769C                                        
msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/
}
exit(0);
}

void SERVER()
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);/*由关键字获得消息队列*/
do
{
msgrcv(msgqid,&msg,1030,0,0);/*从队列msgid接受消息msg*/
printf("(server)receive\n");
}while(msg.mtype!=1);/*消息类型为1时,释放队列*/
msgctl(msgqid,IPC_RMID,0);//delete signal
exit(0);
}

main()
{
if(fork())
SERVER();
else
CLIENT();
wait(0);
}

记录结果

操作系统——实验三(进程间通信)——3.3.3_第1张图片

分析

message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次sendmessage后才receivemessage.这一点有助于理解消息转送的实现机理。

消息通信的特点:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源。(摘自实验指导书)

 

你可能感兴趣的:(计算机基础,操作系统笔记,Linux)