操作系统实验三、进程通信
一、实验目的
1、了解和熟悉Linux支持的消息通信机制、管道道通信、共享存储区机制及信息量机制。
2、掌握利用Linux系统的进程通信机制(IPC)实现进程间交换数据的方法。
二、实验内容
1、进程通信
使用系统调用pipe()建立一条管道线:两个子进程P1和P2分别向管道各写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
父进程则从管道中读出来自两个了进程的信息,显示在屏幕上。
要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。(可以通过sleep()将自身进入睡眠)
2、 消息的创建,发送和接收.
(1) 使用系统调用msgget(), msgsnd(), msgsrv()及msgctl()编制一长度为1K的消息(如个人通信录信息)的发送和接收程序.
(2) 使用共享存储区相关的系统调用 shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序.
(3) 比较上述两种消息通信机制中数据传输的时间。
三、设计原理(或方案)及相关算法
-
管道通信 创建一条管道,子进程写入数据,父进程写出数据。在父进程中使用 wait() 函数,这样在子进程执行 完毕之前,父进程一直要等待。
调用pipe()建立一条管道,两个子进程分别向管道写入一句话,在父进程中使用wait()函数,使父进程等待子进程执行结束,依次输出P1、P2发来的消息。
-
消息的创建,接受和发送
(1)消息队列通信 设计一个结构体来充当缓冲区,存储消息。之后使用msgget(), msgsnd(), msgsrv()及msgctl() 等函数来 实现消息的发送和接受。
(2)使用shmget(),shmat(),sgmdt(),shmctl()等函数实现存储区的共享,轮流使用存储区来接收、发送消息
四、结果分析
2.1
2.2
五、源代码
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>void main()
{pid_t pid_1, pid_2, fd[2];char buf[50], s[50];pipe(fd);while ((pid_1 = fork()) == -1);if (pid_1 == 0){lockf(fd[1], 1, 0);sprintf(buf, "Child 1 is sending message");write(fd[1], buf, 50);lockf(fd[1], 0, 0);exit(0);}else{while ((pid_2 = fork()) == -1);if (pid_2 == 0){lockf(fd[1], 1, 0);sprintf(buf, "Child 2 is sending message");write(fd[1], buf, 50);lockf(fd[1], 0, 0);exit(0);}else{wait(0);read(fd[0], s, 50);printf("%s \n", s);wait(0);read(fd[0], s, 50);printf("%s \n", s);exit(0);}}
}
2.1
#include<stdio.h>
#include<sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75struct 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;printf("(client)send\n");msgsnd(msgqid,&msg,1024,0);}exit(0);
}
void SERVER(){msgqid = msgget(MSGKEY,0777|IPC_CREAT);do{msgrcv(msgqid,&msg,1024,0,0);printf("(server)receive\n");}while(msg.mtype!= 1);msgctl(msgqid,IPC_RMID,0);
}int main(){if(fork()){SERVER();wait(0);} else {CLIENT();}return 0;
}
2.2
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define SHMKEY 75int shmid ,i;
int *addr;void CLIENT(){int i;shmid = shmget(SHMKEY,1024,0777|IPC_CREAT);addr = shmat(shmid,0,0);for(i=9;i>=0;i--){while (*addr != -1);printf("(client)send\n");*addr = i;}exit(0);
}void SERVER(){do{while ( *addr == -1);printf("(server)receive\n");if(*addr != 0)*addr = -1;}while(*addr);wait(0);shmctl(shmid,IPC_RMID,0);
}int main(){shmid = shmget(SHMKEY,1024,0777|IPC_CREAT);addr = shmat(shmid,0,0);*addr = -1;if(fork()){SERVER();wait(0);} else {CLIENT();}return 0;
}