实验8:进程间高级通信
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
msg.mtype=pid;
/*消息类型为 client 进程标识数*/
*pint=getpid();
/*获取 server 进程标识数*/
msgsnd(msgqid,&msg,sizeof(int),0); /*发送消息*/
exit(0);
}
main()
{
while((i=fork())==-1); /*创建进程 1*/
if(!i)server();
while((i=fork())==-1); /*创建进程 2*/
if(!i) client();
wait(0);
wait(0);
}
运行结果:[root@localhost ~]# gcc -o lsj lsj.c
[root@localhost ~]# ./lsj
(server):serving for client pid=26681
(client):receive reply from pid=26680
示例 3:编写一段程序,使其用共享存储区来实现两个进程之间的进程通信。进程 A 创建一 个长度为 512 字节的共享内存,并显示写入该共享内在的数据;进程 B 将共享内存附加到 自己的地址空间,并向共享内在中写入数据。
#include <sys/types.h>
示例 2:编写一段程序,使其用消息缓冲队列来实现 client 进程和 server 进程之间的 通信。Server 进程先建立一个关键字为 SVKEY(如 75)的消息队列,然后等待接收类型 为 REQ(如 1)的消息;在收到请求消息后,它便显示字符串“serving for client”和 接收到的 client 进程的进程标识数,表示正在为 client 进程服务;然后再向 client 进程发送一应答消息,该消息的类型是 client 进程的进程标识数,而正文则是 server 进程自己的标识数。Client 进程则向消息队列发送类型为 REQ 的消息(消息的正文为自 己的进程标识数)以取得 sever 进程的服务,并等待 server 进程发来的应答;然后显示 字符串“receive reply from”和接收到的 server 进程的标识数。
exit(0);
}
void A( )
{
shmid=shmget(SHMKEY,512,0777|IPC_CREAT); /*创建共享存储区*/
addr=shmat(shmid,0,0);
/*获取首地址*/
printf("get %s",addr);
exit(0);
}
main( )
{
while ((i=fork( ))==-1);
4、实验报告的内容与书写 以书面形式记录下你的每一步过程,包括输入、输出信息,遇到的问题和解决的办法。
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
int pid;
// 定义进程变量
main() {
int fd[2];
char OutPipe[300], InPipe[300];
// 定义两个字符数组
pipe(fd);
// 创建管道
while ((pid = fork( )) == -1); // 如果进程创建不成功,则空循环
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75
struct msgform
{ long mtype;
char mtext[250];
}msg;
int msgqid,pid,*pint,i;
printf("%s\n", InPipe); // 显示读出的数据
exit(0);
// 父进程结束
}
}
运行结果:[root@localhost ~]# gcc -o b b.c
[root@localhost ~]# ./b
Child's PID=13807
is sending a message to parent!
if (!i) A();
while ((i=fork( ))==-1);
if (!i) B();
wait(0);
wait(0);
}
运行结果:[root@localhost ~]# gcc -o a a.c
[root@localhost ~]# ./a
get I LOVE YOU FOREVER
分析:进程 A 创建共享空间,并显示共享空间的数据,进程 B 打开共享空间,并向共享空 间写入字符串" I LOVE YOU FOREVER".
要求每个同学登录后系统后,要在自己的家目录内容以自己(拼音)名字或学号,创建 一个子目录(已有者可以不再创建)。以后所有工作都要在自己的目录内进行。建议以后的 实验都在同台计算机上做,这样可以保持连续性。
用户要按通常实验要认真书写实验报告。
4、实验过程
示例 1:编写一段程序,使其用管道来实现父子进程之间的进程通信。子进程向父进程发送 自己的进程标识符,以及字符串“is sending a message to parent”。父进程则通过 管道读出子进程发来的消息,将消息显示在屏幕上,然后终止。
msgrcv(msgqid,&msg,250,1,0); /*接收消息*/
pint=(int *)msg.mtext;
/*把正文的内容传给 pint,并强制转换类型*/
pid=*pint;
/*获得 cilent 进程标识数*/
printf("(server):serving for client pid=%d\n",pid);
/*打开共享存储区*/
addr=shmat(shmid,0,0);
/*获得共享存储区首地址*/
memset(addr,'\0',512);
//将 addr 的 512 字节设置成字符'\0'
ຫໍສະໝຸດ Baidu
strncpy(addr,argv[0],512); //将数组 argv 的前 512 字节存入共享区 addr
#include <sys/shm.h>
#include <sys/ipc.h>
#include<string.h>
#define SHMKEY 75
int shmid,i; char *addr;
char *argv[ ]={"I LOVE YOU FOREVER"};
void B( )
{
shmid=shmget(SHMKEY,512,0777);
void client()
{
msgqid=msgget(MSGKEY,0777); /*打开 75#消息队列*/
pid=getpid();
pint=(int *)msg.mtext;
*pint=pid;
msg.mtype=1;
/*消息类型为 1*/
msgsnd(msgqid,&msg,sizeof(int),0);
msgrcv(msgqid,&msg,250,pid,0);
/*接收消息*/
printf("(client):receive reply from pid=%d\n",*pint); /*显示 server
进程标识数*/
exit(0);
}
void server( )
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*创建 75#消息队列*/
实验 8:进程间高级通信
1、实验目的
(1)掌握如何利用管道机制、消息缓冲队列、共享存储区机制进行进程间的通信; (2)加深对上述通信机制的理解。
2、实现设备
一台装有 Windows 操作系统和 Linux 机系统的微机或服务器。
3、实验方法与注意事项
实验室内的实验环境与系统是共用设施,请不要在系统内做对系统或对其他用户不安全 的事情。
if (pid == 0)
{ lockf(fd[1], 1, 0);
// 如果子进程创建成功,pid 为进程号 // 锁定管道
sprintf(OutPipe, "Child's PID=%d\n%s",getpid(),"is sending a
message to parent!\n");
// 给 Outpipe 赋值
write(fd[1], OutPipe, 50); // 向管道写入数据
sleep(5);
// 等待读进程读出数据
lockf(fd[1], 0, 0);
// 解除管道的锁定
exit(0);
// 结束进程
}
else {
wait(0); // 等待子进程结束
read(fd[0], InPipe, 50); // 从管道中读出数据