《实验五:进程间通信》由会员分享,可在线阅读,更多相关《实验五:进程间通信(8页珍藏版)》请在人人文库网上搜索。
1、精选文库 实验五:进程间通信 实验目的: 学会进程间通信方式:无名管道,有名管道,信号,共享内存 实验要求: (一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道 (二)在进程中为 SIGBUS注册处理函数,并向该进程发送SIGBUS信号 (三)创建一共享内存,实现放进程间通信 实验器材: 软件:安装了 Linux的vmware虚拟机 硬件:PC机一台 实验步骤: (一)无名管道的使用 1、编写实验代码 pip e rw.c #in clude #in clude #in clude #i nclude #in clude #in clude int mai n() int。
2、 pip e_fd2; p id_t p id; char buf_r100; char* p _wbuf; int r_num; memset(buf_r,0,sizeof(buf_r); /*创建管道*/ if(pipe(pip e_fd)0) /父进程执行代码 /1、父进程先关闭了管道的读端 /2、向管道写入字符串数据 /3、关闭写端,并等待子进程结束后退出 return 0; 2、编译应用程序 pip e_rw.c root(9locdlhost pipe# Is pipe rw.c root(ailocdlhost pipe# gcc pipe_rw, c -o pipe_rw 3、。
3、运行应用程序 roottalocalhost pipe# ./pipe_rw parent writel Hello! parent write? Pipe! 10 numbers read from the pipe is Hello Pipe 子进程先睡两秒让父进程先运行,父进程分两次写入“hello ”和“pip e”,然后阻塞等 待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进 程退出后也退出 4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的 读端和写端。我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关。
4、掉读 端,读的进程最好关闭掉写端 (二) 信号处理 1、编写实验代码 sig bus.c #in clude #i nclude #in clude 1、自定义信号处理函数,处理SIGBUS信号,打印捕捉到信号即可 int mai n() prin tf(Wait ing for sig nal SIGBUS n ); 2、注册信号处理函数 P ause();/将进程挂起直到捕捉到信号为止 exit(O); | 用signal系统调用为 SIGBUS信号注册信号处理函数my_fune,然后将进程挂起等待 SIGBUS信号。所以需要向该进程发送SIGBUS信号才会执行自定义的信号处理函数 2、编。
5、译应用程序 sig_bus.e * rootlocalhiost pipe# gicc sig bus*o sig bus 3、运行应用程序 先先一个终端中运行 sig_bus,会看到进程挂起,等待信号 roottaiocalhost pipe 1# ./sig bus Waiting for signal SIGBUS 然后在另一个终端中,查找到运行 号给这个进程 sig_bus这个产生的进程号,用kill命令发送SIGBUS信 rootlocalhoist Earning: root root root 电 Iccalriost r root总localHQSt tcpcllent# ps。
6、 tax, perhaps a 0.2 101.01503 O.e 101.0390S tepclientJ# kilt tCDClient1# -aux i girep sig bus bogus -7 See 315 pts/3 664 pts/2 -BUS /M r/share/doc/proeps-3.2.7/FA3 S+ 01:00 a : 00 SLg_bLiS R+ G1:000: OG grp sig bus 8 我们可以看到前面挂起的进程在接收到这个信号后的处理 (rootlocalhot pipej# ./sigbus Waiting for signal SIGBUS I。
7、 have get siGBUS I roottlocalhiost pi pel# I have get SIGBUS 这样一句话 用自定义信号处理函数my_func来处理,所以打印了 (三)共享内存 1、本实验利用共享内存完成两个进程之间的通信,发送端的消息类型设置为该进程的 进程号(可以取其他值),接收端接收消息(类似消息队列的功能),这里同时需要采用信号 量为同步机制完善两个进程间的通信。 2、下面是共享内存缓冲区的数据结构的定义 /* shm com.h */ #ifndef #defi ne SHM_COM_H SHM_COM_H #in elude #in elude #in e。
8、lude #in elude #in elude #in elude #in elude #define SHM BUFF SZ 2048 struct shm_buff int p id; char bufferSHM_BUFF_SZ; ; #e ndif /* SHM COM H */ 以下是发送端的部分程序,请完善信号量的操作代码 /* P roducer.c */ #in elude shm_com.h #in clude in t ig no re_sig nal(void) sig nal(SIGINT, SIG_IGN); sig nal(SIGST OP, SIG_IGN); 。
9、sig nal(SIGQUIT, SIG_IGN); return 0; int mai n() void *shared_memory = NULL; struct shm_buff *shm_buff_i nst; char bufferBUFSIZ; 防止程序非正常退出*/ */ int shmid, semid; igno re_sig nal(); /* /* 创建一个信号量 /* 初始值为1 */ 创建共享内存 shmid = shmget(ftok(., b), sizeof(struct shm_buff), 0666|l PC_CREAT); if (shmid = -1) 。
10、/* */ P error(shmget failed); 删除信号量 exit(1); 将共享内存地址映射到当前进程地址空间 shared_memory = shmat(shmid, (void*)0, 0); /* */ if (shared_memory = (void*)-1) P error(shmat); 删除信号量 exit(1); prin tf(Memory attached at %Xn, (in t)shared_memory); /*获得共享内存的映射地址*/ shm_buff_i nst = (struct shm_buff *)shared_memory; do p。
11、rin tf(E nter some text to the shared memory(e nter quit to exit):); /*向共享内存写入数据*/ if (fgets(shm_buff_i nst-buffer, SHM_BUFF_SZ, stdi n) = NULL) P error(fgets); sem_v(semid); break; shm_buff_ in st- pid = get pi d(); while(str ncmp( shm_buff_ in st-buffer, quit, 4) != 0); /*删除信号量*/ */ /*删除共享内存到当前进程地。
12、址空间中的映射 if (shmdt(shared_memory) = 1) p error(shmdt); exit(1); exit(0); 以下是接收端程序部分,请完善信号量操作的代码 /* customer.c */ #in clude shm_com.h int mai n() void *shared memory = NULL; struct shm_buff *shm_buff_i nst; int shmid, semid; /*获得信号量*/ /*获得共享内存 */ shmid = shmget(ftok(., b), sizeof(struct shm_buff), 066。
13、6|l PC_CREAT); if (shmid = -1) P error(shmget); exit(1); 将共享内存地址映射到当前进程地址空间 shared_memory = shmat(shmid, (void*)0, 0); if (shared_memory = (void*)-1) /* */ p error(shmat); exit(1); prin tf(Memory attached at %Xn, (in t)shared_memory); /*获得共享内存的映射地址*/ shm_buff_i nst = (struct shm_buff *)shared_memory。
14、; do prin tf(Sharedmemory was writte n by p rocess %d :%s, shm_buff_ in st- pid, shm_buff_ in st-buffer); if (str ncmp( shm_buff_ in st-buffer, quit, 4) = 0) break; shm_buff_ in st- pid = 0; memset(shm_buff_i nst-buffer, 0, SHM_BUFF_SZ); while(1); /*删除共享内存到当前进程地址空间中的映射 if (shmdt(shared_memory) = -1)。
15、 */ /* p error(shmdt); exit(1); 删除共享内存 */ if (shmctKshmid, IPC RMID, NULL) = -1) p error(shmctl(I PC_RMID); exit(1); exit(0); 3、实验结果 roGto*local host ?4emory atta匚hud EnLtir bonie text Fnter sojie text Enter sou* text -7-2 ,/producer B7r50000 tile shared the shared the shared at to to meniuryfenter 。
16、* Quit * memcrytenter quit memory(enter quit to to to exit):firbt exit):second exit):quLt Shared memry was irit Lcn by proccay 12860 :first. Shared me wry was ikritten by p roc(;ss lS60 :second Shared memry upitten by process 12860 :qui I at lac tied yt 閃Y390Q0 上机报告要求: 1 总结 pipe(), signal(), shmget()函数定义原型, 2、利用有名管道FIFO实现类似第一个实验的功能,一个程序 LinUX ”,另一个程序fifo_write.c读数据并打印出来。 rootlocalhust S-7-z ./culoniui Memory 返回值和参数的意义 fifo read.c写数据”Hi。