实验项目四 进程通信
一、 实验目的
1. 了解什么是消息,熟悉消息传送原理。 2. 了解和熟悉共享存储机制。 3. 掌握消息的发送与接收的实现方法。
二、 实验内容
1. 根据消息传送机理,使用系统调用msgget( ), msgsnd( ), msgrev( ), 及msgctl( )编制一长度为1k的消息发送和接收的程序,要求在程序中完成10次消息的发送和接收,每次发送消息结束和接收消息结束都需给出相应的屏幕提示,且每次发送的的内容不少于一个字符,并能在接收端输出。 2. 根据共享存储区原理,使用系统调用shmget( ), shmat( ), shmdt( ), 及shctl( )编制程序,要求创建一个长度为1k的共享存储区,并完成10次数据的发送和接收,每次发送数据结束和接收数据结束都需给出相应的屏幕提示,且每次发送的的数据应能在接收端输出。
三、 源程序及运行结果
1. 源程序:
#include
#define MSGKEY 75 struct msgform {
long mtype;
char mtext[1024]; }msg;
int msgqid,i; void client( ) {
int i;
msgqid=msgget(MSGKEY,0777|IPC_CREAT); for(i=10;i>=1;i--) { msg.mtype=i;
msg.mtext[i]='k'-i; printf(\ msgsnd(msgqid,&msg,1024,0); } }
main() {
client( ); }
#include
#define MSGKEY 75 struct msgform {
long mtype;
char mtext[1024]; }msg;
int msgqid,i; void server( ) {
msgqid=msgget(MSGKEY,0777|IPC_CREAT); do {
msgrcv(msgqid,&msg,1024,0,0); printf(\ printf(\
}while(msg.mtype!=1); msgctl(msgqid, IPC_RMID,0); }
main()
{
server(); }
运行结果:
2. 源程序:
#include
#define SHMKEY 75 int shmid,i; int *addr; void client( ) { int i,n=1;
shmid=shmget(SHMKEY,1024,0777); /*打开共享存储区*/ addr=shmat(shmid,0,0); /*获得共享存储区首地址*/ for(i=0;i<10;i++) {while (*addr!=-1); printf(\ *addr=n++;
printf(\ sleep(1); }
exit(0);
}
int main( ) { client( ); }
#include
#define SHMKEY 75 int shmid,i; int *addr; void server( )
{ shmid=shmget(SHMKEY,1024,0777|IPC_CREAT); /*创建共享存储区*/ for(i=0;i<10;i++) {
addr=shmat(shmid,0,0); /*获取首地址*/ *addr=-1;
while (*addr==-1); printf(\
printf(\ (server) received\\n\ sleep(1); }
shmctl(shmid,IPC_RMID,0); /*撤消共享存储区,归还资源*/ exit(0); }
int main( ) { server( ); }
运行结果:(截图)
四、 实验分析与总结
对实验运行结果进行分析:试比较实验中两种方法实现进程通信的不同之处。 分析:
(1)消息队列的建立比共享区的设立消耗的资源少.前者只是一个软件上设定的问题,后者需要对硬件操作,实现内存的映像,当然控制起来比前者复杂.如果每次都重新进行队列或共享的建立,共享区的设立没有什么优势。
(2)当消息队列和共享区建立好后,共享区的数据传输,受到了系统硬件的支持,不耗费多余的资源;而消息传递,由软件进行控制和实现,需要消耗一定的CPU资源.从这个意义上讲,共享区更适合频繁和大量的数据传输.
(3)消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源.而共享队列如果不借助其他机制进行同步,接受数据的一方必须进行不断的查询,白白浪费了大量的CPU
资源.可见消息方式的使用更加灵活.
总结:message的传送和控制并不保证完全同步,当一个程序不在激活状态的时候,它完全可能继续睡眠,造成了上面的现象,在多次send message 后才recieve message。这一点有助于理解消息传送的实现机理。对于共享存储区通信当client端发送了数据后,并没有任何措施通知server端数据已经发出,需要由client的查询才能感知。此时,client端并没有放弃系统的控制权,仍然占用CPU的时间片。只有当系统进行调度时,切换到了server进程,再进行应答。