实验五:进程间通信

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

实验五:进程间通信

●实验目的:

学会进程间通信方式:无名管道,有名管道,信号,共享内存

●实验要求:

(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号

(三)创建一共享内存,实现放进程间通信

●实验器材:

软件:安装了Linux的vmware虚拟机

硬件:PC机一台

●实验步骤:

(一)无名管道的使用

1、编写实验代码pipe_rw.c

#include

#include

#include

#include

#include

#include

int main()

{

int pipe_fd[2];

pid_t pid;

char buf_r[100];

char* p_wbuf;

int r_num;

memset(buf_r,0,sizeof(buf_r));

/*创建管道*/

if(pipe(pipe_fd)<0)

{

printf("pipe create error\n");

return -1;

}

/*创建子进程*/

if((pid=fork())==0) //子进程执行代码

{

//1、子进程先关闭了管道的写端

//2、让父进程先运行,这样父进程先写子进程才有内容读

//3、读取管道的读端,并输出数据

//4、关闭管道的读端,并退出

}

else if(pid>0) //父进程执行代码

{

//1、父进程先关闭了管道的读端

//2、向管道写入字符串数据

//3、关闭写端,并等待子进程结束后退出

}

return 0;

}

2、编译应用程序pipe_rw.c

3、运行应用程序

子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出

4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关掉读端,读的进程最好关闭掉写端

(二)信号处理

1、编写实验代码sig_bus.c

#include

#include

#include

//1、自定义信号处理函数,处理SIGBUS信号,打印捕捉到信号即可

int main()

{

printf("Waiting for signal SIGBUS \n ");

//2、注册信号处理函数

pause();//将进程挂起直到捕捉到信号为止

exit(0);

}

用signal系统调用为SIGBUS信号注册信号处理函数my_func,然后将进程挂起等待SIGBUS信号。所以需要向该进程发送SIGBUS信号才会执行自定义的信号处理函数

2、编译应用程序sig_bus.c

3、运行应用程序

先先一个终端中运行sig_bus,会看到进程挂起,等待信号

然后在另一个终端中,查找到运行sig_bus这个产生的进程号,用kill命令发送SIGBUS信号给这个进程

我们可以看到前面挂起的进程在接收到这个信号后的处理

用自定义信号处理函数my_func来处理,所以打印了I have get SIGBUS这样一句话

(三)共享内存

1、本实验利用共享内存完成两个进程之间的通信,发送端的消息类型设置为该进程的进程号(可以取其他值),接收端接收消息(类似消息队列的功能),这里同时需要采用信号量为同步机制完善两个进程间的通信。

2、下面是共享内存缓冲区的数据结构的定义

/* shm_com.h */

#ifndef SHM_COM_H

#define SHM_COM_H

#include

#include

#include

#include

#include

#include

#include

#define SHM_BUFF_SZ 2048

struct shm_buff

{

int pid;

char buffer[SHM_BUFF_SZ];

};

#endif /* SHM_COM_H */

以下是发送端的部分程序,请完善信号量的操作代码

/* producer.c */

#include "shm_com.h"

#include

int ignore_signal(void)

{

signal(SIGINT, SIG_IGN);

signal(SIGSTOP, SIG_IGN);

signal(SIGQUIT, SIG_IGN);

return 0;

}

int main()

{

void *shared_memory = NULL;

struct shm_buff *shm_buff_inst;

char buffer[BUFSIZ];

int shmid, semid;

ignore_signal(); /* 防止程序非正常退出*/

/* 创建一个信号量*/

/* 初始值为1 */

/* 创建共享内存*/

shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);

if (shmid == -1)

{

perror("shmget failed");

//删除信号量

exit(1);

}

/* 将共享内存地址映射到当前进程地址空间*/

shared_memory = shmat(shmid, (void*)0, 0);

相关文档
最新文档