《Linux操作系统设计实践》实验二:进程通信

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《Linux操作系统设计实践》实验二:进程通信
实验目的:
进一步了解和熟悉 Linux 支持的多种 IPC 机制,包括信号,管道,消息队列,信号量,共享内存。

实验环境: redhat
实验内容:
(1)进程间命名管道通信机制的使用:使用命名管道机制编写程序实现两个进程间的发送接收信息。

(2)进程间消息队列通信机制的使用:使用消息队列机制自行编制有一定长度的消息(1k 左右)的发送和接收程序。

(3)进程间共享存储区通信机制的使用:使用共享内存机制编制一个与上述(2)功能相同的程序。

并比较分析与其运行的快慢。

实验代码验证:
(1).使用命名管道机制编写程序实现两个进程间的发送接收信息。

#include <stdio.h>
#include <stdlib.h>
#define FIFO_FILE "MYFIFO"
int main(int argc, char *argv[])
{
FILE *fp;
int i;
if (argc<=1)
{
printf("usage: %s <pathname>\n",argv[0]); exit(1);
}
if ((fp = fopen(FIFO_FILE, "w")) == NULL) {
printf("open fifo failed. \n");
exit(1);
}
for (i = 1; i < argc; i++)
{
if (fputs(argv[i],fp) == EOF)
{
printf("write fifo error. \n");
exit(1);
}
if (fputs(" ",fp) == EOF)
{
printf("write fifo error. \n"); exit(1);
}
}
fclose(fp);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
int main()
{
FILE *fp;
char readbuf[80];
if ((fp = fopen(FIFO_FILE, "r")) == NULL) {
umask(0);
mknod(FIFO_FILE, S_IFIFO | 0666, 0);
}
else
{
fclose(fp);
}
while (1)
{
if ((fp = fopen(FIFO_FILE, "r")) == NULL) {
printf("open fifo failed. \n");
exit(1);
}
if (fgets(readbuf, 80, fp) != NULL)
{
printf("Received string :%s \n", readbuf); fclose(fp);
}
else
{
if (ferror(fp))
{
printf("read fifo failed.\n");
exit(1);
}
}
}
return 0;
}
实验结果:
Server.c将client.c写入的字符输出。

分析:client.c 程序通过fopen(“MYPI O“,”w“)这个系统调用在当前目录下创建了一个名为MYPIPO的只写文件。

将第一个以后的命令行参数,写进MYPIPO文件中;server.c程序首先使用fopen ()系统调用试图打开MYPIPO文件,但是MYPIPO文件是只读文件,故调用失败,所以,接着调用umask (),和mknod()两个系统调用设置文件MYPIPO的属性,将文件改为有名管道类型,且是允许读写的文件(属主,属组,其他用户皆是)。

最后通过fgets()这个系统调用将有名管道文件内的内容读到字
符数组readbuf中,并显式。

(2)
使用消息队列机制自行编制有一定长度的消息(1k 左右)的发送和接收程序。

#include<stdio.h>
#include <string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define key 1
#define buffersize 1024
int main()
{
struct SMSG
{
long mtype;
char mtext[buffersize];
}msg ;
int pid;
int p;
while ((p = fork()) == -1);
if(p == 0)
{
sleep(5);
pid = msgget(key, IPC_CREAT | 0600); msgrcv(pid, &msg, buffersize, 1, 0);
printf("receive msg is:%s\n",msg.mtext);
msgctl(pid, IPC_RMID, 0);
}
else
{
pid = msgget(key, IPC_CREAT | 0600);
msg.mtype = 1;
strcpy(msg.mtext, "This is the message which the parent have
sent!");
while ((msgsnd(pid, &msg, buffersize, 0)) == -1);
}
return 0;
}
实验结果:
显示:receive msg is:This is the message which the parent have sent!
分析:msg.c程序用fork()系统调用创建一个子进程。

其中父进程通过
msgget()系统调用创建一个消息对列,并定义所要发送的消息的类型号,最后通过msgsnd()系统调用将消息传递给消息队列;
子进程先sleep()系统调用暂停一会儿,保证父子进程并发执行时,父进程能够尽量早的多执行,接着当调用msgget()系统调用,得到和父进程所创建的那个消息队列的id号,是他们两关联的是同一个消息队列,然后用msgrcv()系统调用将类型号为1的消息队列中的第一个消息拷贝到消息msg中。

并输出。

(3)使用共享内存机制编制一个与上述(2)功能相同的程序。

并比较分析与其运行的快慢。

#include<stdio.h>
#include <string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define buffersize 1024
#define Key 1
int main()
{
int p;
while ((p = fork()) == -1);
if (p == 0)
{
int pid;
sleep(5);
pid = shmget(Key, buffersize, IPC_CREAT | 0600);
char *addr;
addr = (char *)shmat(pid, NULL, 0);
printf("receive msg is:%s\n", addr);
shmdt(addr);
}
else
{
int pid;
pid = shmget(Key, buffersize, IPC_CREAT | 0600);
char *addr;
addr = (char *)shmat(pid, NULL, 0);
strcpy(addr, " This is the message which the parent have sent!"); shmdt(addr);
}
return 0;
}
实验结果:
显示:receive msg is:This is the message which the parent have sent!
分析:shm.c程序的不同之处是在内存中开辟了内存区域,并通过shmget()获
得该共享内存的id号,然后用shmat()把共享内存链接到addr处,实现数据的交换和共享,最后用shmdt断开于共享内存的链接。

与(2)相比,则3会比较快一点。


为(2)消息的发送与接收需要对消息队列的消息进行拷贝和删除操作。

而且要每次
消息的传递都需要系统调用来实现。

而(3)只是开始时通过系统调用建立共享内存
的链接。

就可以在共享内存内进行数据的交换和共享。

而且之后的操作不用在系统调用,直到断开链接。

相关文档
最新文档