Linux进程间通信程序设计
- 格式:doc
- 大小:39.42 KB
- 文档页数:3
实验六:进程间通信实验目的:学会进程间通信方式:无名管道,有名管道,信号,消息队列,实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台实验步骤:(一)无名管道的使用1、编写实验代码pipe_rw.c#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>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));//将buf_r初始化char str1[]=”parent write1 “holle””;char str2[]=”parent write2 “pipe”\n”;r_num=30;/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{//1、子进程先关闭了管道的写端close(pipe_fd[1]);//2、让父进程先运行,这样父进程先写子进程才有内容读sleep(2);//3、读取管道的读端,并输出数据if(read(pipe_fd[0],buf_r, r_num)<0){printf(“read error!”);exit(-1);}printf(“%s\n”,buf_r);//4、关闭管道的读端,并退出close(pipe_fd[1]);}else if(pid>0) //父进程执行代码{//1、父进程先关闭了管道的读端close(pipe_fd[0]);//2、向管道写入字符串数据p_wbuf=&str1;write(pipe_fd[1],p_wbuf,sizof(p_wbuf));p_wbuf=&str2;write(pipe_fd[1],p_wbuf,sizof(p_wbuf));//3、关闭写端,并等待子进程结束后退出close(pipe_fd[1]);}return 0;}/***********************#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>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));//将buf_r初始化char str1[]="holle";char str2[]="pipe";r_num=10;/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{close(pipe_fd[1]);//1、子进程先关闭了管道的写端//2、让父进程先运行,这样父进程先写子进程才有内容读//3、读取管道的读端,并输出数据if(read(pipe_fd[0],buf_r, r_num)<0){printf("read1 error!");exit(-1);}printf("\nparent write1 %s!",buf_r);sleep(1);if(read(pipe_fd[0],buf_r, r_num)<0){printf("read2 error!");exit(-1);}printf("\nparent write2 %s!",buf_r);close(pipe_fd[1]);//4、关闭管道的读端,并退出exit(1);//printf("child error!");}else if(pid>0) //父进程执行代码{close(pipe_fd[0]);//1、父进程先关闭了管道的读端p_wbuf=str1;//2、向管道写入字符串数据write(pipe_fd[1],p_wbuf,sizeof(str1));sleep(1);p_wbuf=str2;write(pipe_fd[1],p_wbuf,sizeof(str2));close(pipe_fd[1]);//3、关闭写端,并等待子进程结束后退出exit(1);//printf("father error!");}return 0;}**************************/2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
《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");。
linux课程设计进程间通信一、教学目标本节课的教学目标是让学生了解和掌握Linux进程间通信的基本概念和常用方法。
知识目标包括:掌握进程间通信的定义、作用和分类;理解Linux系统中进程间通信的机制和原理。
技能目标包括:学会使用Linux系统中的管道、信号和共享内存等通信方法;能够编写简单的Linux进程间通信程序。
情感态度价值观目标包括:培养学生对Linux系统的兴趣和好奇心,提高学生对计算机操作系统的基本认识;培养学生团队合作精神和自主学习能力。
二、教学内容本节课的教学内容主要包括Linux进程间通信的概念、分类和机制,以及常用的进程间通信方法。
首先,介绍进程间通信的定义和作用,让学生了解进程间通信的重要性。
然后,讲解Linux系统中进程间通信的机制和原理,包括管道、信号和共享内存等方法。
接下来,通过实例演示和编程实践,让学生掌握这些通信方法的用法和特点。
最后,结合实际应用场景,讨论进程间通信在操作系统中的应用和意义。
三、教学方法为了达到本节课的教学目标,采用多种教学方法相结合的方式进行教学。
首先,采用讲授法,向学生讲解进程间通信的基本概念和原理。
其次,通过案例分析法,分析实际应用场景中的进程间通信问题,引导学生学会运用所学知识解决实际问题。
然后,利用实验法,让学生动手实践,编写进程间通信程序,加深对通信方法的理解和记忆。
最后,采用讨论法,鼓励学生积极参与课堂讨论,培养团队合作精神和批判性思维。
四、教学资源为了支持本节课的教学内容和教学方法的实施,准备以下教学资源。
首先,教材《Linux操作系统原理与应用》,作为学生学习的基础资料。
其次,参考书《Linux进程间通信》,为学生提供更深入的理论学习资料。
再次,多媒体教学课件,用于直观展示进程间通信的原理和实例。
最后,实验室设备,包括计算机和网络设备,用于学生进行进程间通信实验。
通过这些教学资源,丰富学生的学习体验,提高学习效果。
五、教学评估本节课的教学评估将采用多种方式,以全面、客观地评价学生的学习成果。
进程间通信Linux 课程设计一、教学目标本课程的教学目标是使学生掌握进程间通信在Linux环境下的基本原理和实现方法。
具体目标如下:1.知识目标:–了解Linux操作系统的基本概念和架构;–理解进程间通信的概念、作用和分类;–掌握Linux下进程间通信的主要方法,如管道、消息队列、共享内存和信号等;–掌握同步机制,如互斥锁、条件变量和信号量等。
2.技能目标:–能够在Linux环境下编写简单的进程间通信程序;–能够分析并解决进程间通信过程中遇到的问题;–能够运用进程间通信的原理和技巧解决实际编程中的问题。
3.情感态度价值观目标:–培养学生的团队协作意识和沟通能力;–培养学生的创新精神和自主学习能力;–培养学生对操作系统和进程间通信领域的兴趣和热情。
二、教学内容本课程的教学内容主要包括以下几个部分:1.Linux操作系统基本概念和架构;2.进程间通信的概念、作用和分类;3.Linux下进程间通信的主要方法:–消息队列;–共享内存;4.同步机制:–条件变量;5.进程间通信实例分析。
三、教学方法为了达到本课程的教学目标,将采用以下教学方法:1.讲授法:用于讲解基本概念、原理和方法;2.案例分析法:通过分析实际案例,使学生更好地理解进程间通信的原理和应用;3.实验法:让学生动手实践,培养实际编程能力;4.讨论法:鼓励学生积极参与课堂讨论,培养团队协作和沟通能力。
四、教学资源为了支持本课程的教学内容和教学方法,将准备以下教学资源:1.教材:《Linux进程间通信》;2.参考书:相关领域的经典著作和学术论文;3.多媒体资料:教学PPT、视频讲座等;4.实验设备:计算机、网络设备等。
五、教学评估为了全面、客观地评估学生的学习成果,本课程将采用以下评估方式:1.平时表现:通过课堂参与、提问、讨论等方式评估学生的积极性、主动性和团队协作能力;2.作业:布置相关的编程练习和研究报告,评估学生的理解和应用能力;3.考试:包括期中和期末考试,以闭卷形式进行,评估学生对进程间通信知识的掌握程度和实际应用能力;4.实验报告:评估学生在实验过程中的动手能力和问题解决能力。
linux进程间通信课程设计一、课程目标知识目标:1. 理解Linux操作系统中进程间通信的基本概念与原理;2. 掌握进程间通信的几种主要机制,如管道、消息队列、共享内存和信号量;3. 学会使用相关API进行进程间数据传输和控制流程;4. 了解进程间同步和互斥的概念,并掌握相关实现方法。
技能目标:1. 能够编写简单的Linux进程间通信程序;2. 能够分析进程间通信程序的执行流程,并解决通信过程中可能出现的常见问题;3. 能够运用所学知识解决实际场景中的进程间通信问题。
情感态度价值观目标:1. 培养学生对操作系统和底层编程的兴趣,激发学生探究新技术的好奇心;2. 培养学生的团队协作精神,提高学生在团队项目中的沟通与协作能力;3. 培养学生严谨、认真的学习态度,使学生认识到编程过程中细节的重要性。
本课程针对高年级计算机专业学生,结合课程性质、学生特点和教学要求,将课程目标分解为具体的学习成果。
通过本课程的学习,学生将掌握Linux进程间通信的基本知识和技能,培养实际编程能力和团队协作精神,为后续学习操作系统及相关领域知识打下坚实基础。
二、教学内容1. 进程间通信概述- 了解进程与线程的概念及区别;- 掌握Linux操作系统中进程间通信的基本需求及分类。
2. 管道通信- 学习管道的基本原理和使用方法;- 掌握无名管道和命名管道(FIFO)的创建、读写操作及注意事项。
3. 消息队列- 了解消息队列的基本概念和原理;- 掌握消息队列的创建、发送、接收和删除操作。
4. 共享内存- 学习共享内存的基本原理和用途;- 掌握共享内存的创建、映射和解除映射操作,以及同步机制。
5. 信号量- 了解信号量的基本概念和用途;- 掌握信号量的创建、P操作和V操作,以及应用场景。
6. 信号- 学习信号的基本概念、分类和作用;- 掌握信号的发送、捕捉和处理方法。
教学内容根据课程目标进行选择和组织,保证科学性和系统性。
本教学内容涵盖教材中关于Linux进程间通信的相关章节,按照教学进度安排,逐一向学生传授各通信机制的基本原理和实际应用。
实验6 Linux进程通信-消息传递一、实验目的:1)掌握操作系统的进程通信原理。
2)熟悉linux的进程通信方式。
3)设计程序,实现消息传递通信。
二、实验原理:1、函数ftok头文件:#include <sys/types.h>#include <sys/ipc.h>原型:key_t ftok(char *fname,int id)说明:系统建立IPC(进程间通信)时必须指定一个ID值,通常情况下该ID值通过ftok 函数得到。
ftok函数把一个已存在的路径名和一个整数标识符转换成一个key_t值,fname 是一个存在的可访问的路径或文件,id必须不能为0。
2、函数msgget头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>原型:int msgget(key_t key,int msgflg);说明:获取与某个键关联的消息队列标识,用来创建新的消息队列或获取已有的消息队列。
第一个参数是关键字值(通常是由ftok()返回的)。
然后此关键字值将会和其他已经存在于系统内核中的关键字值比较。
第二个参数为IPC_CREAT时,如果内核中没有此队列,则创建它,并且返回一个新创建的消息队列的标识符。
失败返回-1。
3、函数fgets头文件:#inclue <stdio.h>原型:char *fgets(char *s,int size,FILE *stream);说明:用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符,读到文件尾或是已读了size-1个字符为止,最后加上\0作为字符串结束。
第三个参数可以是文件流,也可以是输入流stdin。
4、比较字符串函数strncmp头文件:#include <string.h>原型:int strncmp(const char *s1,const char *s2,int n);说明:若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值。
进程间通信Linux 课程设计一、课程目标知识目标:1. 理解Linux操作系统中进程间通信的基本概念,掌握不同通信机制的工作原理及适用场景。
2. 掌握使用信号、管道、消息队列、共享内存和信号量等Linux进程间通信机制。
3. 学会分析进程间通信的需求,并能够设计合理的通信方案。
技能目标:1. 能够编写基于Linux进程间通信机制的程序,实现多个进程的数据交换和控制同步。
2. 能够运用所学知识解决实际编程问题,提高程序的并发性和效率。
3. 能够使用调试工具对进程间通信程序进行调试,找出并修复潜在问题。
情感态度价值观目标:1. 培养学生对操作系统和进程间通信的兴趣,激发学习热情。
2. 培养学生的团队合作意识,提高沟通能力,使其在项目协作中发挥积极作用。
3. 引导学生认识到掌握进程间通信技术在软件开发中的重要性,提高职业素养。
课程性质:本课程为高年级计算机专业选修课,侧重于Linux进程间通信技术的实际应用。
学生特点:学生已具备一定的操作系统基础,熟悉C语言编程,具有一定的编程实践能力。
教学要求:结合理论教学与实践操作,注重培养学生的动手能力和问题解决能力,使学生在实际项目中能够灵活运用所学知识。
在教学过程中,将课程目标分解为具体的学习成果,以便进行有效的教学设计和评估。
二、教学内容1. 进程间通信基本概念- 进程与线程的区别与联系- 进程间通信的需求与意义2. Linux进程间通信机制- 信号:信号的概念、分类、发送与接收- 管道:无名管道与命名管道的创建、读写操作- 消息队列:消息队列的创建、发送与接收- 共享内存:共享内存的创建、映射与解除映射- 信号量:信号量的创建、P操作与V操作3. 进程间通信编程实践- 使用信号实现进程同步- 使用管道实现兄弟进程间通信- 使用消息队列、共享内存和信号量实现进程间数据交换4. 进程间通信调试与优化- 常见通信问题的调试方法- 提高进程间通信效率的技巧5. 教学案例分析- 分析实际项目中进程间通信的应用案例- 结合教材内容,进行案例讲解与讨论教学大纲安排:第1周:进程间通信基本概念及信号机制第2周:管道与消息队列机制第3周:共享内存与信号量机制第4周:进程间通信编程实践第5周:调试与优化方法及案例分析教学内容与教材关联性:教学内容紧密围绕教材中关于Linux进程间通信的相关章节,结合实际编程需求,确保学生学以致用。
实验五Linux进程间通信实验五Linux进程间通信姓名学号1.实验⽬的1)熟悉在C语⾔源程序中使⽤Linux所提供的系统调⽤界⾯的⽅法;2)掌握Linux中⼦进程的创建⽅法以及调度执⾏情况,理解进程与程序的区别;3)掌握软中断信号的使⽤,了解使⽤软中断通信实现异步事件的⽅法;4)掌握⽗⼦进程使⽤管道进⾏通信的⽅法,了解管道通信的特点和上的限制。
2.实验内容1)⽗进程创建⼦进程(1)实现⽗进程创建⼀个⼦进程,返回后⽗⼦进程都分别循环输出字符串“I am parent.”或“I am child.”5次,每输出1次后使⽤sleep(1)延时1秒,然后再进⼊下⼀循环。
【编程⽂件如下】【执⾏结果如下】(2)在源程序中连续使⽤4个fork(),⽽不⽤if()进⾏返回值的判断,在4个fork()语⾔后⾯输出字符“A”,观察并分析该程序编译连接执⾏后的输出结果。
【编程⽂件如下】(3)由⽗进程创建⼀个⼦进程,⼦进程的功能史输出26个英⽂字母,使⽤execl()加载⼦进程的程序。
【编程⽂件letters.c如下】【编程⽂件execl.c如下】【运⾏结果如下】2)软中断的使⽤(1)编写⼀个程序循环显⽰“How are you?”,当键盘输⼊Ctrl+C的组合键后中断循环显⽰,执⾏软中断程序,软中断程序的功能是修改循环变量的值终⽌循环,然后输出“Byebye”。
【编程⽂件how.c如下】【运⾏结果如下】3)管道的使⽤:(1)编写⼀个程序,实现:⽗进程使⽤系统调⽤pipe()创建⼀个⽆名管道;(2)创建2个⼦进程,分别向管道各发下⾯中1条信息后结束:Child 1 is sending a message to parent!Child 2 is sending a message to parent!【编程⽂件child12.c如下】【运⾏结果如下】3.实验思考1)如果连续创建多个⼦进程⽽不使⽤条件进⾏各⾃空间的分隔,会出现什么情况?【答】:运⾏结果将会出现16个“A”。
实验二Linux进程间通信1.实验目的(1)分析进程争用临界资源的现象,学习解决进程互斥的方法;(2)学习如何利用进程的“软中断”、管道机制进行进程间的通信,并加深对上述通信机制的理解;(3)了解系统调用pipe( )、msgget( )、msgsnd( )、msgrcv( )、msgctl( )、shmget( )、shmat( )、shmdt( )、shmctl( )的功能和实现过程,利用共享存储区机制进行进程间通信。
2.实验内容(1)进程的控制编写一段程序,使用系统调用fork()创建两个子进程。
各进程循环显示不同的信息(如20次):父进程显示:“parent:”加上进程ID,子进程分别显示:“Child1:”(或“Child2:”)加上自己的进程ID。
观察程序执行时屏幕上出现的现象,并分析原因,进一步理解各个进程争夺临界资源(显示器)的情况。
接着在程序中使用系统调用locking( )来给每一个进程加锁,实现进程之间的互斥,试观察并分析出现的现象。
(2)进程的软中断通讯编制一段程序,实现进程的软中断通讯:使用系统调用fork( )创建两个子进程;再使用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);在捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发信号;子进程捕捉到信号后分别输出下列信息后终止:Child process1 is killed by parent!Child process2 is killed by parent!父进程等待两个子进程都终止以后,输出如下信息后终止:Parent process in killed!(3)进程的管道通讯编制一段程序,实现进程的管道通讯:使用系统调用pipe( )建立一条管道线;两个子进程分别循环向这条管道写一句话:Child 1 is sending a message!Child 2 is sending a message!而父进程则循环从管道中读出信息,显示在屏幕上。
实验六:进程间通信●实验目的:学会进程间通信方式:无名管道,有名管道,信号,消息队列,●实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据●实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台●实验步骤:(一)无名管道的使用write(pipe_fd[1],p_wbuf,sizeof(str1));sleep(1);p_wbuf=str2;write(pipe_fd[1],p_wbuf,sizeof(str2));close(pipe_fd[1]);//3、关闭写端,并等待子进程结束后退出exit(1);//printf("father error!");}return 0;}**************************/2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关掉读端,读的进程最好关闭掉写端(二)信号处理#include <signal.h>{fprintf(stderr,"cannot handle SIGBUS\n");exit(EXIT_FAILURE);}pause();//将进程挂起直到捕捉到信号为止exit(0);return 0;}***************************/用signal系统调用为SIGBUS信号注册信号处理函数my_func,然后将进程挂起等待SIGBUS信号。
第 30 章 进程 4. 进程间通信每个进程各自有不同的用户地址空间, 任何一个进程的全局变量在另一个进程中 都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区, 进程 1 把数据从用户空间拷到内核缓冲区,进程 2 再从内核缓冲区把数据读走, 内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。
如下图所示。
图 30.6. 进程间通信4.1. 管道管道是一种最基本的 IPC 机制,由 pipe 函数创建:#include <unistd.h>int pipe(int filedes[2]);调用 pipe 函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读 端一个写端, 然后通过 filedes 参数传出给用户程序两个文件描述符, filedes[0] 指向管道的读端,filedes[1]指向管道的写端(很好记,就像 0 是标准输入 1 是标准输出一样)。
所以管道在用户程序看起来就像一个打开的文件,通过 read(filedes[0]);或者 write(filedes[1]);向这个文件读写数据其实是在读 写内核缓冲区。
pipe 函数调用成功返回 0,调用失败返回-1。
开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信。
图 30.7. 管道得到两个文件描述符指向管道的两端。
1. 父进程调用 pipe 开辟管道, 2. 父进程调用 fork 创建子进程,那么子进程也有两个文件描述符指 向同一管道。
3. 父进程关闭管道读端,子进程关闭管道写端。
父进程可以往管道里 写,子进程可以从管道里读,管道是用环形队列实现的,数据从写 端流入从读端流出,这样就实现了进程间通信。
例 30.7. 管道#include <stdlib.h> #include <unistd.h> #define MAXLINE 80int main(void) { int n; int fd[2]; pid_t pid; char line[MAXLINE];if (pipe(fd) < 0) { perror("pipe"); exit(1); } if ((pid = fork()) < 0) { perror("fork"); exit(1); } if (pid > 0) { /* parent */ close(fd[0]); write(fd[1], "hello world\n", 12); wait(NULL); } else { /* child */close(fd[1]); n = read(fd[0], line, MAXLINE);write(STDOUT_FILENO, line, n); } return 0; }使用管道有一些限制:•两个进程通过一个管道只能实现单向通信,比如上面的例子,父进 程写子进程读,如果有时候也需要子进程写父进程读,就必须另开 一个管道。
Linux进程间通信消息队列实现两个进程间通信例⼦:通过消息队列实现两个进程间通信,⼀个进程从终端输⼊数据,通过消息队列发送,另⼀个进程通过消息队列接收数据 ⽂件1 创建进程1 终端输⼊通过消息队列发送数据#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>struct msgbuf //消息结构体{long types;char msg[20];};struct msgbuf mymsgbuf; //定义消息结构变量int main(int argc, const char *argv[]){key_t key;int msgid;mymsgbuf.types = 100; //给消息结构赋值key = ftok("./app",'a'); //建⽴key值if(key < 0){perror("ftok fail ");exit(1);}// 创建消息队列,如果消息队列存在,errno 会提⽰ eexist// 错误,此时只需要直接打开消息队列即可msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);if(msgid < 0){if(errno == EEXIST) //⽂件存在错误提⽰{msgid = msgget(key,0666);//打开消息队列}else//其他错误退出{perror("msgget fail ");exit(1);}}while(1) //循环从终端获取数据,然后通过消息队列发送出去,输⼊ “quit” 结束循环{fgets(mymsgbuf.msg, 10, stdin); //终端获取消息写⼊消息队列中//发送消息msgsnd(msgid, &mymsgbuf, sizeof(mymsgbuf)-sizeof(long),0);if(strstr(mymsgbuf.msg, "quit")!=NULL){break;}}//删除消息队列msgctl(msgid, IPC_RMID, NULL);return 0;}⽂件 2 创建进程2 ,接收消息队列的数据,打印到终端上#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>struct msgbuf //消息结构体{long types;char b[20];};struct msgbuf mymsgbuf, recvbuf; //定义消息结构变量int main(int argc, const char *argv[]){key_t key;int msgid;mymsgbuf.types = 100; //给消息结构赋值key = ftok("./app",'a'); //建⽴key值if(key < 0){perror("ftok fail ");exit(1);}// 创建消息队列,如果消息队列存在,errno 会提⽰ eexist// 错误,此时只需要直接打开消息队列即可msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);if(msgid < 0){if(errno == EEXIST) //⽂件存在错误提⽰{msgid = msgget(key,0666);//打开消息队列}else//其他错误退出{perror("msgget fail ");exit(1);}}while(1) //接收到 “quit” 结束循环{//接收消息msgrcv(msgid,&recvbuf,sizeof(mymsgbuf)-sizeof(long),100,0); //recvbuf 是接收消息的结构体,其中的b是实际的数据if(strstr(recvbuf.b, "quit") != NULL){break;}printf("recvbuf: %s", recvbuf.b); //}//删除消息队列msgctl(msgid, IPC_RMID, NULL);return 0;}测试:。
计算机与信息技术学院设计性实验报告
一、实验目的
(1)理解进程概念;
(2)理解并掌握多进程开发模式;
(3)理解并掌握Linux平台进程间数据的传送方法。
二、总体设计
(1)实验内容:编写程序实现进程的管道通信。
用系统调用pipe( )建立一管道,创建两个二个子进程P1和P2分别向管道各写一句话:
Message from child P1!
Message from child P2!
父进程从管道中读出二个来自子进程的信息并显示。
(2)设计原理:
所谓管道,是指能够连接一个写进程和一个读进程、并允许它们进行通信的一个共享文件,又称为pipe文件。
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。
通过管道的信息流
三、实验步骤:
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
# include <string.h>
#define BUFSIZE 100
int pid1,pid2;
int main()
{
int fd[2];
char buf_out [BUFSIZE], buf_in [BUFSIZE];
if (pipe(fd) < 0)
{ printf("pipe error\n"); exit(1); } /*创建一个管道*/
if ((pid1 = fork()) < 0) /*创建子进程1*/
{ printf("fork1 failure\n"); exit(1); }
else if (pid1 == 0)
{
lockf(fd[1],1,0);
strcpy(buf_out," Message from child P1!"); /*把串放入数组buf_out中*/
write(fd[1],buf_out,BUFSIZE); /*向管道写长为BUFSIZE字节的串*/ sleep(5); /*自我阻塞5秒*/
lockf(fd[1],0,0);
exit(0);
}
else
{
while((pid2=fork( ))==-1); /*创建子进程2*/
if(pid2==0)
{ lockf(fd[1],1,0); /*互斥*/
sprintf(buf_out,"Message from child %d!",getpid());
write(fd[1], buf_out,BUFSIZE);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{ wait(0); /*同步*/
read(fd[0], buf_in,BUFSIZE); /*从管道中读长为BUFSIZE字节的串*/
printf("%s\n", buf_in);
wait(0);
read(fd[0], buf_in,BUFSIZE);
printf("%s\n", buf_in);
exit(0);
}
}
return 0;
}
四、结果分析与总结
延迟5秒后显示
Message from child P1!
再等待5秒显示
Message from child P2!
总结:本实验通过父进程用pipe( )建立一个无名管道,再用fork函数创建了两个子进程,父进程从管道中读出二个来自子进程的信息并显示,利用锁定与解锁实现了两个子进程向管道互斥通信。
通过本次实验了解到进程的概念,知道了什么是管道,并且熟悉了LINUX支持的管道通信方式,开始时对子进程P1和P2为什么能够对管道进行操作产生疑问,后来明白子进程P1和P2之所以能够对管道进行操作是其调用pipe()进程并识别该管道描述符,此次实验使我获益匪浅。
教师签名:
年月日。