实验三 进程通信doc(DOC)
实验三 进程同步
集美大学诚毅学院信息工程系实验报告课程名称计算机操作系统序号名称实验三进程同步姓名孙幸杰学号2011957032专业计算1191 日期13.11.22成绩教师洪联系评语:1.实验目的:掌握用Linux信号灯集机制实现两个进程间的同步问题2.实验环境Win7系统虚拟机下运行的Linux系统。
3.实验内容司机与售票员问题是两个进程的同步问题,司机要启动汽车前,要检查售票员车门是否已经关好;售票员要打开车门之前要等司机把车停稳.要求:需要的信号灯: System V信号灯实现用于控制司机是否可以启动车辆的的信号灯 S1=0用于控制售票员是否可以开门的信号灯 S2=04.实验程序(有详细注释)//---------------------------------------------------//这是一个公共汽车的驾驶员与售票员之间的同步问题//一个进程模拟驾驶员,一个进程模拟售票员;//驾驶员的动作:启动车辆--驾驶车辆--到站停车//售票员的动作:关门--售票--开门;//售票员把车门关好后,驾驶员才能启动汽车;//当驾驶员在一个站把车子停稳后,售票员方能打开车门;////本程序采用System V的信号灯集实现两者的同步// 2010.10.8//-----------------------------------------------------#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <stdio.h>#include <time.h>#include <stdlib.h>union semun{int val;//仅用于SETVAL命令struct semid_ds *buf;//用于IPC_SET等命令ushort *array;//用于SETALL等命令};//用于信号灯初始化//semid--信号灯的ID//val--欲设置的信号灯初值//sn--信号灯集的分量void seminit(int semid,int val,int sn) {union semun arg;arg.val=val;semctl(semid,sn,SETVAL,arg);};//实现信号灯的P操作//semid--信号灯的ID//sn--信号灯集的分量void semdown(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;//P操作为-1op.sem_flg=0;semop(semid,&op,1);}//实现信号灯的V操作//semid--信号灯的ID// sn--信号灯集的分量void semup(int semid, int sn){/*define V operating*/struct sembuf op;op.sem_num=sn;op.sem_op=1;//V操作为1op.sem_flg=0;semop(semid,&op,1);}main(){int i,j;key_t semkey;char *pathname="./driver.c";int semid;int rrand;srand((int)time(0));//用于产生随机延时 semkey=ftok(pathname,45);if(semkey==-1){printf("Error:create a key error!\n");exit(-1);}semid=semget(semkey,2,IPC_CREAT | 0666);if(semid==-1){printf("Error:create semaphore error!\n");exit(-1);}seminit(semid,0,0);//对信号灯集的0号分量进行初始化seminit(semid,0,1);//对信号灯集的1号分量进行初始化if(fork()==0) //Create a process{//子进程作为驾驶员进程for(i=1;i<10;i++){semdown(semid,0);//等待售票员关门printf("Driver(pid:%d): Start the bus.\n",getpid());printf("Driver(pid:%d): Traveling....\n",getpid());rrand=1+(int)(6.0*rand()/(RAND_MAX+1.0));//产生一个(1-6)的随机数表示车辆的行驶时间sleep(rrand);printf("Driver(pid:%d): Arrive at a station. stop!\n",getpid()); semup(semid,1);//唤醒售票员}}else{//父进程作为售票员进程for(j=1;j<10;j++){printf("Conductor(pid:%d):Close all doors.\n",getpid());semup(semid,0);//唤醒司机printf("Conductor(pid:%d):Ticketing...\n",getpid());semdown(semid,1); //等待汽车到站printf("Conductor(pid:%d):Open all doors.\n",getpid());sleep(1);}}}5.实验结果及其分析输入程序:程序:编译:运行结果:6.实验小结完成本实验后,我对基本的额进程间的通信有了初步的了解。
操作系统实验二实验报告
操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。
通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。
三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。
2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。
3、为新进程指定可执行文件的路径、命令行参数、进程属性等。
4、编写代码来等待新进程的结束,并获取其退出代码。
(二)进程同步实验1、设计一个生产者消费者问题的模型。
2、使用信号量来实现生产者和消费者进程之间的同步。
3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。
4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。
(三)进程通信实验1、选择使用管道来实现进程之间的通信。
2、创建一个匿名管道,父进程和子进程分别读写管道的两端。
3、父进程向管道写入数据,子进程从管道读取数据并进行处理。
四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。
通过观察进程的创建和执行过程,加深了对进程概念的理解。
(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。
分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。
(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。
数据能够准确地在进程之间传递,验证了管道通信的有效性。
五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。
通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。
(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。
《计算机操作系统》实验指导书
《计算机操作系统》实验指导书(适合于计算机科学与技术专业)湖南工业大学计算机与通信学院二O一四年十月前言计算机操作系统是计算机科学与技术专业的主要专业基础课程,其实践性、应用性很强。
实践教学环节是必不可少的一个重要环节。
计算机操作系统的实验目的是加深对理论教学内容的理解和掌握,使学生较系统地掌握操作系统的基本原理,加深对操作系统基本方法的理解,加深对课堂知识的理解,为学生综合运用所学知识,在Linux环境下调用一些常用的函数编写功能较简单的程序来实现操作系统的基本方法、并在实践应用方面打下一定基础。
要求学生在实验指导教师的帮助下自行完成各个操作环节,并能实现且达到举一反三的目的,完成一个实验解决一类问题。
要求学生能够全面、深入理解和熟练掌握所学内容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌握,并且能够进行简单分析和判断;能够熟练使用Linux用户界面;掌握操作系统中进程的概念和控制方法;了解进程的并发,进程之间的通信方式,了解虚拟存储管理的基本思想。
同时培养学生进行分析问题、解决问题的能力;培养学生完成实验分析、实验方法、实验操作与测试、实验过程的观察、理解和归纳能力。
为了收到良好的实验效果,编写了这本实验指导书。
在指导书中,每一个实验均按照该课程实验大纲的要求编写,力求紧扣理论知识点、突出设计方法、明确设计思路,通过多种形式完成实验任务,最终引导学生有目的、有方向地完成实验任务,得出实验结果。
任课教师在实验前对实验任务进行一定的分析和讲解,要求学生按照每一个实验的具体要求提前完成准备工作,如:查找资料、设计程序、完成程序、写出预习报告等,做到有准备地上机。
进行实验时,指导教师应检查学生的预习情况,并对调试过程给予积极指导。
实验完毕后,学生应根据实验数据及结果,完成实验报告,由学习委员统一收齐后交指导教师审阅评定。
实验成绩考核:实验成绩占计算机操作系统课程总评成绩的20%。
指导教师每次实验对学生进行出勤考核,对实验效果作记录,并及时批改实验报告,综合评定每一次的实验成绩,在学期终了以平均成绩作为该生的实验成绩。
电大操作系统实验报告3_ 进程管理实验
电大操作系统实验报告3_ 进程管理实验电大操作系统实验报告 3 进程管理实验一、实验目的进程管理是操作系统的核心功能之一,本次实验的目的是通过实际操作和观察,深入理解进程的概念、状态转换、进程调度以及进程间的通信机制,掌握操作系统中进程管理的基本原理和方法,提高对操作系统的整体认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C 语言,开发工具为 Visual Studio 2019。
三、实验内容及步骤(一)进程的创建与终止1、编写一个 C 程序,使用系统调用创建一个子进程。
2、在父进程和子进程中分别输出各自的进程 ID 和父进程 ID。
3、子进程执行一段简单的计算任务,父进程等待子进程结束后输出结束信息。
以下是实现上述功能的 C 程序代码:```cinclude <stdioh>include <stdlibh>include <unistdh>int main(){pid_t pid;pid = fork();if (pid < 0) {printf("创建子进程失败\n");return 1;} else if (pid == 0) {printf("子进程:我的进程 ID 是%d,父进程 ID 是%d\n",getpid(), getppid());int result = 2 + 3;printf("子进程计算结果:2 + 3 =%d\n", result);exit(0);} else {printf("父进程:我的进程 ID 是%d,子进程 ID 是%d\n",getpid(), pid);wait(NULL);printf("子进程已结束\n");}return 0;}```编译并运行上述程序,可以观察到父进程和子进程的输出信息,验证了进程的创建和终止过程。
(二)进程的状态转换1、编写一个 C 程序,创建一个子进程,子进程进入睡眠状态一段时间,然后被唤醒并输出状态转换信息。
16207318邓嘉操作系统实验三
操作系统实验第三次实验进程同步实验指导老师:***学号:********姓名:***操作系统第三次实验进程同步实验指导老师:谭朋柳学生:16207318邓嘉4.1 实验目的加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。
了解Linux 系统中IPC 进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。
4.2 实验说明在linux 系统中可以利用进程间通信(interprocess communication )IPC 中的3 个对象:共享内存、信号灯数组、消息队列,来解决协作并发进程间的同步与互斥的问题。
1)共享内存是OS 内核为并发进程间交换数据而提供的一块内存区(段)。
如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映射到自己私有的地址空间中。
如果一进程更新了段中数据,那么其他进程立即会看到这一更新。
进程创建的段也可由另一进程读写。
linux 中可用命令ipcs -m 观察共享内存情况。
$ ipcs -m------ Shared Memory Segments --------key shmid owner perms bytes nattch status 0x00000000 327682 student 600 393216 2 dest0x00000000 360451 student 600 196608 2 dest 0x00000000 393220 student 600 196608 2 destkey 共享内存关键值shmid 共享内存标识owner 共享内存所由者(本例为student)perm 共享内存使用权限(本例为student 可读可写)byte 共享内存字节数nattch 共享内存使用计数status 共享内存状态上例说明系统当前已由student 建立了一些共享内存,每个都有两个进程在共享。
操作系统上机实验报告
操作系统上机实验报告实验一进程的建立1.实验目的学会通过基本的Windows进程控制函数,由父进程创建子进程,并实现父子进程协同工作。
2.实验软硬件环境Dev-C++3.实验内容创建两个进程,让子进程读取一个文件,父进程等待子进程读取完文件后继续执行,实现进程协同工作。
进程协同工作就是协调好两个进程,使之安排好先后次序并以此执行,可以用等待函数来实现这一点。
当需要等待子进程运行结束时,可在父进程中调用等待函数。
4.实验程序及分析实验程序源代码如下:父进程:#include<stdio.h>#include<windows.h>int main(){STARTUPINFO si;PROCESS_INFORMA TION pi; //当Windows创建新进程时,将使用这两个结构体的有关成员。
所以在创建子进程之前应该对结构体进行声明和初始化。
ZeroMemory(&pi,sizeof(pi));ZeroMemory(&si,sizeof(si));si.cb=sizeof(STARTUPINFO);if(CreateProcess("lab1.2.exe",NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL ,NULL,&si,&pi))//创建一个新进程,若是成功,就返回1,进而实现if选择{printf("子进程已创建~\n");int i,sum=0;for(i=1;i<=100;++i){sum+=i;printf("sum=%d\n",sum);} //进行1+2+3+….+100计算WaitForSingleObject(pi.hProcess,INFINITE); FILE *fp;fp=fopen("date.txt","r");char ch=fgetc(fp); //创建文件并打开while(ch!=EOF){putchar(ch);ch=fgetc(fp);}fclose(fp); //关闭文件}elseprintf("子进程创建失败~\n");return 0;}子进程:#include<stdio.h>#include<stdlib.h>int main(){printf("子进程运行~\n");FILE *fp;if(fp=fopen("date.txt","w")){printf("已经创建文件!\n");int i;for(i=48;i<58;i++) fputc(i,fp);fputc('\n',fp);fclose(fp);printf("已经写入数据:"); //向文本中写入数据fp=fopen("date.txt","r");char ch=fgetc(fp);while(ch!=EOF){putchar(ch);ch=fgetc(fp); //输出数据}fclose(fp);}else printf("创建文件失败!\n");system("pause");return 0;}5. 实验截图说明及分析6. 实验心得体会掌握了父进程创建子进程的方法,对操作系统多线程认识更深了。
进程管理实验报告分析(3篇)
第1篇一、实验背景进程管理是操作系统中的一个重要组成部分,它负责管理计算机系统中所有进程的创建、调度、同步、通信和终止等操作。
为了加深对进程管理的理解,我们进行了一系列实验,以下是对实验的分析和总结。
二、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。
2. 进一步认识并发执行的实质。
3. 分析进程争用资源的现象,学习解决进程互斥的方法。
4. 了解Linux系统中进程通信的基本原理。
三、实验内容1. 使用系统调用fork()创建两个子进程,父进程和子进程分别显示不同的字符。
2. 修改程序,使每个进程循环显示一句话。
3. 使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号,实现进程的终止。
4. 分析利用软中断通信实现进程同步的机理。
四、实验结果与分析1. 实验一:父进程和子进程分别显示不同的字符在实验一中,我们使用fork()创建了一个父进程和两个子进程。
在父进程中,我们打印了字符'a',而在两个子进程中,我们分别打印了字符'b'和字符'c'。
实验结果显示,父进程和子进程的打印顺序是不确定的,这是因为进程的并发执行。
2. 实验二:每个进程循环显示一句话在实验二中,我们修改了程序,使每个进程循环显示一句话。
实验结果显示,父进程和子进程的打印顺序仍然是随机的。
这是因为并发执行的进程可能会同时占用CPU,导致打印顺序的不确定性。
3. 实验三:使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号在实验三中,我们使用signal()捕捉键盘中断信号(按c键),然后通过kill()向两个子进程发送信号,实现进程的终止。
实验结果显示,当按下c键时,两个子进程被终止,而父进程继续执行。
这表明signal()和kill()在进程控制方面具有重要作用。
4. 实验四:分析利用软中断通信实现进程同步的机理在实验四中,我们分析了利用软中断通信实现进程同步的机理。
进程通信的实验报告
一、实验目的1. 理解进程通信的概念和作用。
2. 掌握进程通信的常用方法,包括管道、消息队列、信号量等。
3. 通过编程实践,加深对进程通信机制的理解和应用。
二、实验环境操作系统:Linux开发环境:gcc三、实验内容1. 管道通信2. 消息队列通信3. 信号量通信四、实验步骤及分析1. 管道通信(1)实验步骤1)创建一个父进程和一个子进程;2)在父进程中创建一个管道,并将管道的读端和写端分别赋给父进程和子进程;3)在父进程中,通过管道的写端发送数据给子进程;4)在子进程中,通过管道的读端接收父进程发送的数据;5)关闭管道的读端和写端;6)结束进程。
(2)实验分析通过管道通信,实现了父进程和子进程之间的数据传递。
管道是半双工通信,数据只能单向流动。
在本实验中,父进程向子进程发送数据,子进程接收数据。
2. 消息队列通信(1)实验步骤1)创建一个消息队列;2)在父进程中,向消息队列中发送消息;3)在子进程中,从消息队列中接收消息;4)删除消息队列;5)结束进程。
(2)实验分析消息队列是一种进程间通信机制,允许不同进程之间传递消息。
消息队列的创建、发送、接收和删除等操作都是通过系统调用实现的。
在本实验中,父进程向消息队列发送消息,子进程从消息队列接收消息,实现了进程间的消息传递。
3. 信号量通信(1)实验步骤1)创建一个信号量;2)在父进程中,对信号量执行P操作,请求资源;3)在子进程中,对信号量执行V操作,释放资源;4)结束进程。
(2)实验分析信号量是一种用于实现进程同步的机制。
在进程通信中,信号量可以用来协调多个进程对共享资源的访问。
在本实验中,父进程和子进程通过信号量实现了对共享资源的同步访问。
五、实验结果1. 管道通信实验结果:父进程成功向子进程发送数据,子进程成功接收数据。
2. 消息队列通信实验结果:父进程成功向消息队列发送消息,子进程成功从消息队列接收消息。
3. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。
进程通讯管理实验报告(3篇)
第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
进程控制与进程通信程序实验报告
进程控制与进程通信程序实验报告一、引言进程是计算机系统中最基本的概念之一,是操作系统中最小的资源管理单位。
进程控制与进程通信是操作系统中重要的内容,涉及到进程的创建、调度和终止,以及进程间的信息传递和同步管理。
本实验旨在通过编写进程控制与进程通信程序,加深对操作系统中进程管理和通信机制的理解。
二、实验目的1. 理解进程的概念和特点,掌握进程的创建、调度和终止方法。
2. 掌握进程通信的基本原理和方法,包括共享内存、管道、消息队列和信号量等。
3. 能够编写简单的进程控制和进程通信程序。
三、实验内容1. 进程控制实验:编写一个程序,实现进程的创建、调度和终止。
通过调用系统调用函数,创建多个子进程,并通过进程控制函数实现父子进程的协作与同步。
2. 进程通信实验:编写一个程序,实现进程间的信息传递和同步管理。
通过共享内存、管道、消息队列或信号量等机制,实现不同进程之间的数据交换和共享。
四、实验步骤1. 进程控制实验:(1)创建父进程和子进程:使用fork()函数创建子进程,并通过判断返回值来区分父子进程。
(2)调度子进程:使用wait()函数等待子进程的结束,以实现父子进程的同步。
(3)终止子进程:使用exit()函数终止子进程的运行。
2. 进程通信实验:(1)共享内存:使用shmget()函数创建共享内存段,使用shmat()函数映射共享内存到进程的地址空间,实现共享数据的读写。
(2)管道:使用pipe()函数创建管道,使用fork()函数创建子进程,通过读写管道实现进程间的数据传输。
(3)消息队列:使用msgget()函数创建消息队列,使用msgsnd()函数向消息队列发送消息,使用msgrcv()函数从消息队列接收消息,实现进程间的消息传递。
(4)信号量:使用semget()函数创建信号量,使用semop()函数对信号量进行P操作和V操作,实现进程间的同步和互斥。
五、实验结果通过实验,我们成功实现了进程的创建、调度和终止,以及进程间的信息传递和同步管理。
操作系统实验报告
操作系统实验报告专业:软件工程姓名:李程星学号:2011221104220092实验一操作系统的用户界面LINUX操作系统提供了图形用户界面和命令行界面,本实验主要熟悉命令行界面,为后续的实验编程做准备。
一、系统启动1. 开机,选择进入Linux系统,约40秒后系统启动成功,系统提示输入用户名:user输入口令:111111 然后进入Linux系统桌面。
2.进入Linux命令行方式单击小红帽图标,选择“系统工具”,单击“终端”图标,出现Linux的shell提示符.....@......$,,即可输入命令。
实验二进程管理一、实验目的(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
二、实验内容1、进程的创建执行下面的程序,分析执行的结果。
#include <stdio.h>main(){ int i;printf("just 1 process.\n");i=fork();if (i==0)printf("I am child.\n");elseif (i>0)printf("I am parent.\n");elseprintf("fork() failed.\n");printf("program end.\n");}输出结果:just 1 process.I am parent.program end.I am a child.program end.2、进程的同步执行下面的程序,分析执行的结果。
#include <stdio.h>main(){ int i;printf("just 1 process.\n");i=fork();if (i>0){printf("I am parent.\n");wait();}elseif (i==0) {printf("I am child.\n");exit(1);}printf("program end.\n");}输出结果:just 1 process.I am parent.I am child.program end.3、进程的延迟执行下面的程序,分析执行的结果。
操作系统实验---进程通信——共享存储区和信号量
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:实验项目名称进程通信——共享存储区和信号量一、实验目的与要求:1、了解和熟悉共享存储机制2、了解和熟悉信号量机制3、熟悉信号量机制中使用的数据结构和信号量机制的操作以及控制。
4、了解共享主存段机制,学会对共享主存段的系统调用。
二、实验设备及软件:1、PC机一台2、Linux操作系统三、实验方法(原理、流程图)一、共享存储区1、共享存储区机制的概念共享存储区(Share Memory)是 UNIX 系统中通信速度最高的一种通信机制。
该机制可使若干进程共享主存中的某一个区域,且使该区域出现(映射)在多个进程的虚地址空间中。
另一方面,一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。
当进程间欲利用共享存储区进行通信时,必须先在主存中建立一共享存储区,然后将它附接到自己的虚地址空间上。
此后,进程对该区的访问操作,与对其虚地址空间的其它部分的操作完全相同。
进程之间便可通过对共享存储区中数据的读、写来进行直接通信。
图示列出二个进程通过共享一个共享存储区来进行通信的例子。
其中,进程 A 将建立的共享存储区附接到自己的 AA’区域,进程 B 将它附接到自己的 BB’区域。
应当指出,共享存储区机制只为进程提供了用于实现通信的共享存储区和对共享存储区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。
因而当用户需要使用该机制时,必须自己设置同步和互斥措施才能保证实现正确的通信。
二、涉及的系统调用1、shmget( )创建、获得一个共享存储区。
系统调用格式: shmid=shmget(key,size,flag)参数定义: int shmget(key,size,flag);key_t key;int size,flag;其中,key是共享存储区的名字;size是其大小(以字节计);flag是用户设置的标志,如IPC_CREAT。
实验三操作系统进程间通信
实验三操作系统进程间通信实验三进程间通信班级:计科f1406 姓名:王家平学号:201416010619一、实验目的:Linux系统的进程通信机构(IPC)允许在任意进程间大批量的交换数据。
本实验的目的是了解和熟悉Linux支持的通信机制、共享存储区机制及信号量机制。
二、实验预备内容:阅读Linux系统的msg.c sem.c shm.c等源码文件,熟悉Linux的三种通信机制。
三、实验内容:(1) 消息的创建,发送和接收(2) 使用系统调用msgget(),msgsnd(), msgrev()及msgctl()编制一长度为1k的消息发送和接收程序。
<程序设计>(1) 为了便于操作和观察结果,用一个程序作为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。
2) SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。
当遇(到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。
SERVER 每接收到一个消息后显示一句“(server)received”。
(3) CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。
最后一个消息,即是SERVER端需要的结束信号。
CLIENT每发送一条信息后显示一句“(client)sent”。
(4) 父进程在SERVER和CLIENT均退出后结束。
(5)四(实验代码1.#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75struct msgform{long mtype;char mtext[1030];}msg;int msgqid,i;void CLIENT(){ int i;msgqid=msgget(MSGKEY,0777);for (i=10;i>=1;i--){msg.mtype=i;printf("(client)sent \n");msgsnd(msgqid,&msg,1024,0); /*发送消息msg入msgid消息队列*/ }exit(0);}void SERVER(){msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*由关键字获得消息队列*/ do{msgrcv(msgqid,&msg,1030,0,0); /*从msgid消息队列接收消息msg*/ printf("(server)received \n");}while(msg.mtype!=1); /*消息类型为1时,释放队列*/msgctl(msgqid,IPC_RMID,0);exit(0);}void main(){while((i=fork())==-1);if(!i) SERVER();while((i=fork())==-1);if(!i) CLIENT();wait(0);wait(0);}2.#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75struct msgform{long mtype;char mtext[1030];}msg;int msgqid,i;CLIENT(){ int i;msgqid=msgget(MSGKEY,0777);for (i=10;i>=1;i--){msg.mtype=i;printf("(client)sent \n");msgsnd(msgqid,&msg,1024,0); /*发送消息msg入msgid消息队列*/ }exit(0);}main(){while((i=fork())==-1); if(!i) CLIENT();wait(0);}。
操作系统实验三进程的管道通信
操作系统实验三进程的管道通信操作系统中的进程通信是指进程之间通过一定机制进行信息传递和交换的过程。
而管道是常用的进程间通信(IPC)机制之一,它提供了一种半双工的通信方式,用于在具有亲缘关系的进程之间进行通信。
本实验以Linux系统为例,介绍进程的管道通信。
一、进程间通信(IPC)概述进程之间的通信是操作系统的重要功能之一,它使得不同进程能够共享信息、协调工作。
Linux系统提供了多种进程间通信的方式,如管道、消息队列、信号、共享内存等。
其中,管道是最简单、最常用的一种进程间通信方式。
二、管道的概念与原理1.管道的概念管道是一种特殊的文件,用于实现具有亲缘关系的进程之间的通信。
整个管道可以看作是一个字节流,其中写入的数据可以被读取。
管道通常是半双工的,即数据只能从一个进程流向另一个进程,而不能反向流动。
2.管道的原理管道的内部实现是通过操作系统的缓冲区来完成的。
当一个进程往管道写入数据时,数据被放置在写管道的缓冲区中。
另一个进程从管道中读取数据时,数据被从读管道的缓冲区中取出。
如果写管道的缓冲区为空,写操作将会阻塞,直到有数据被写入为止。
同样,如果读管道的缓冲区为空,读操作将会阻塞,直到有数据可读为止。
三、管道的使用步骤1.打开管道在Linux系统中,使用`pipe`系统调用来创建管道。
它接受一个包含两个整数的参数数组,返回0表示成功,负数表示失败。
成功创建管道后,会得到两个文件描述符,分别代表读管道和写管道。
2.进程间通信在有亲缘关系的进程中,可以使用`fork`系统调用来创建一个子进程。
父进程和子进程都可以使用管道进行读写操作。
父进程可以关闭写管道描述符,子进程关闭读管道描述符,即父进程只负责写入数据,子进程负责读取数据。
3.写入数据父进程在写管道描述符上调用`write`函数来向管道写入数据。
该函数的返回值为成功写入的字节数,返回-1表示写入失败。
4.读取数据子进程在读管道描述符上调用`read`函数来从管道读取数据。
操作系统实验报告三
操作系统实验报告三一、实验目的本次操作系统实验的目的在于深入了解操作系统的进程管理、内存管理和文件系统等核心功能,通过实际操作和观察,增强对操作系统原理的理解和掌握,提高解决实际问题的能力。
二、实验环境本次实验在 Windows 10 操作系统环境下进行,使用了 Visual Studio 2019 作为编程工具,并借助了相关的操作系统模拟软件和调试工具。
三、实验内容与步骤(一)进程管理实验1、创建多个进程使用 C++语言编写程序,通过调用系统函数创建多个进程。
观察每个进程的运行状态和资源占用情况。
2、进程同步与互斥设计一个生产者消费者问题的程序,使用信号量来实现进程之间的同步与互斥。
分析在不同并发情况下程序的执行结果,理解进程同步的重要性。
(二)内存管理实验1、内存分配与回收实现一个简单的内存分配算法,如首次适应算法、最佳适应算法或最坏适应算法。
模拟内存的分配和回收过程,观察内存的使用情况和碎片产生的情况。
2、虚拟内存管理了解 Windows 操作系统的虚拟内存机制,通过查看系统性能监视器观察虚拟内存的使用情况。
编写程序来模拟虚拟内存的页面置换算法,如先进先出(FIFO)算法、最近最少使用(LRU)算法等。
(三)文件系统实验1、文件操作使用 C++语言对文件进行创建、读写、删除等操作。
观察文件在磁盘上的存储方式和文件目录的结构。
2、文件系统性能测试对不同大小和类型的文件进行读写操作,测量文件系统的读写性能。
分析影响文件系统性能的因素,如磁盘碎片、缓存机制等。
四、实验结果与分析(一)进程管理实验结果1、创建多个进程在创建多个进程的实验中,通过任务管理器可以观察到每个进程都有独立的进程 ID、CPU 使用率、内存占用等信息。
多个进程可以并发执行,提高了系统的资源利用率。
2、进程同步与互斥在生产者消费者问题的实验中,当使用正确的信号量机制时,生产者和消费者能够协调工作,不会出现数据不一致或死锁的情况。
实验三_进程间的通信
本科实验报告专用纸课程名称操作系统原理成绩评定实验项目名称进程间的通信指导教师实验项目编号实验项目类型实验地点学生姓名学号学院系专业实验时间年月日上午~月日上午温度℃湿度一、实验目的和要求1.实验目的:1.学习如何利用管道机制或消息缓冲队列进行进程间的通信,并加深对上述通信机制的理解。
提高学生分析问题和解决问题的能力,并学习撰写规范的科学研究报告(论文)。
2.实验要求:了解系统pipe(),msgsnd(),msgrcv()的功能和实现过程。
二、实验原理和主要内容1.实验内容:(1)编写一段程序,使用管道来实现父子进程之间的进程通信。
子进程向父进程发送自己的进程表示符,以及某字符串。
父进程则通过管道读出子进程发来的消息,将消息显示在屏幕上,然后终止。
(2)编写一段程序,使其用消息缓冲队列来实现client和server 进程之间的通信。
2.实验原理:(使用的系统调用命令说明或算法及程序详细设计)3.实验函数说明(1)包含头文件#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>(2)msgsnd()函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//将消息送入消息队列参数:msqid:消息队列的识别码。
msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下struct msgbuf {long mtype; /* 消息类型,必须> 0 */char mtext[1]; /* 消息文本*/};msgsz:消息的大小。
msgtyp:从消息队列内读取的消息形态。
如果值为零,则表示消息队列中的所有消息都会被读取。
msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。
实验三 进程的管道通信实验
实验三进程的管道通信一、实验目的(1)了解什么是管道(2)熟悉UNIX/LINUX支持的管道通信方式二、实验学时4学时三、实验内容编写程序实现进程的管道通信。
用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。
四、实验指导一、什么是管道UNIX系统在OS的发展上,最重要的贡献之一便是该系统首创了管道(pipe)。
这也是UNIX系统的一大特色。
所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。
1、有名管道一个可以在文件系统中长期存在的、具有路径名的文件。
用系统调用mknod( )建立。
它克服无名管道使用上的局限性,可让更多的进程也能利用管道进行通信。
因而其它进程可以知道它的存在,并能利用路径名来访问该文件。
对有名管道的访问方式与访问其他文件一样,需先用open( )打开。
2、无名管道一个临时文件。
利用pipe( )建立起来的无名文件(无路径名)。
只用该系统调用所返回的文件描述符来标识该文件,故只有调用pipe( )的进程及其子孙进程才能识别此文件描述符,才能利用该文件(管道)进行通信。
当这些进程不再使用此管道时,核心收回其索引结点。
二种管道的读写方式是相同的,本文只讲无名管道。
3、pipe文件的建立分配磁盘和内存索引结点、为读进程分配文件表项、为写进程分配文件表项、分配用户文件描述符4、读/写进程互斥内核为地址设置一个读指针和一个写指针,按先进先出顺序读、写。
为使读、写进程互斥地访问pipe文件,需使各进程互斥地访问pipe文件索引结点中的直接地址项。
名词解释 进程通信
名词解释进程通信1.引言1.1 概述概述进程通信是指在多个进程间进行数据和信息的交流和共享的过程。
在现代计算机系统中,多任务和并发执行已经成为了一种常见的需求。
为了实现这种需求,进程通信作为一种重要的机制被引入。
多个进程之间需要相互协作和共享数据,以完成复杂的任务和操作。
进程通信提供了一种可靠和高效的方式来实现不同进程之间的交流和合作。
通过进程间的通信,进程可以共享数据、传递消息、同步行为和协调操作,使得多进程的系统可以高效地完成各种任务。
进程通信的基本原理是通过使用共享内存、消息传递、管道等机制来实现进程间的数据交换。
共享内存是一种让多个进程共享同一段内存区域的机制,进程可以直接读写共享内存来交换数据。
消息传递则是通过进程间传递消息的方式来进行通信,进程可以发送和接收消息来实现数据的交换和传递。
管道则是一种半双工的通信机制,可用于常见的进程间通信。
进程通信的重要性不言而喻。
它使得多个进程可以同时并行执行,共享资源,高效地完成各种任务。
进程通信不仅仅是在操作系统层面发挥作用,它也在许多应用程序中扮演着重要的角色。
比如,一个网络服务器需要同时处理多个客户端的请求,就需要通过进程通信来协调不同进程之间的工作,以提供高并发的服务。
进程通信的应用领域非常广泛。
它在操作系统、网络通信、分布式系统、并行计算等领域都有着重要的应用。
在操作系统中,进程通信是操作系统的核心功能之一,它为不同进程提供了交流和合作的机制。
在网络通信中,进程通信被广泛应用于客户端和服务器之间的数据交换和通信。
在分布式系统和并行计算中,进程通信是实现任务分发和协调的重要手段。
综上所述,进程通信作为一种重要的机制,为多进程系统的协作和数据交换提供了基础。
它通过共享内存、消息传递、管道等机制,使得不同进程可以高效地交流和合作,实现了并发执行和多任务处理的需要。
进程通信的应用领域广泛,不仅在操作系统中起着核心作用,还在网络通信、分布式系统和并行计算等领域有重要的应用。
进程通信实验报告
西安电子科技大学《操作系统原理》实验报告题目:进程通信实验报告班级: 030912姓名:王增祥学号: 03091168实验内容补充说明:一、分析和设计1.理论分析每个Windows进程都是由一个执行体进程块(EPROCESS)表示。
API函数CreatProcess 可以创建进程,采用管道技术可以实现进程间的相互通信。
建立pipe,进程以及其子进程就可以对该管道进程读写共享,管道读写操作利用,write、read、close进行。
父进程利用pipe 发送消息,子进程利用该pipe接收父进程发来的消息;子进程利用管道向父进程发送应答,父进程利用该pipe接受应答。
2.总体设计1、利用CreatProcess函数创建进程。
2、创建管道,实现进程间的通信二、详细实现1、创建界面,采用Botton、列表框等控件创建父子界面如下图:父进程界面:子进程界面:其中父进程各个空间创建类向导如图:子进程创建类向导如图:2.父进程编写(1)创建管道:(2)创建子进程:(3)消息发送(4)消息接受3.子进程编写(1)发送消息(2)读消息三、实验结果点击创建子进程按钮:在创建子进程之后进行进程间的通信如下图四、心得体会1、从试验的角度了解了进程间是怎样利用管道进行通信的,了解了进程间通信的实际过程2、进一步掌握了MFC的初步编程技巧,知道了怎样调试程序。
3进一步了解了,API函数的应用,明白了怎样进行界面编程。
4、进一步熟悉了在进行进程通信的编写过程中的各个细节。
六、附录Process_Father.cpp#include "stdafx.h"#include "Process_Father.h" //包含已编写的Process_Father.h头文件#include "Process_FatherDlg.h" //包含已编写的Process_FatherDlg.h头文件//进行宏定义#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif//创建父进程BEGIN_MESSAGE_MAP(CProcess_FatherApp, CWinApp)//{{AFX_MSG_MAP(CProcess_FatherApp)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSGON_COMMAND(ID_HELP, CWinApp::OnHelp)END_MESSAGE_MAP()// CProcess_FatherApp constructionCProcess_FatherApp::CProcess_FatherApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}// The one and only CProcess_FatherApp objectCProcess_FatherApp theApp;// CProcess_FatherApp initializationBOOL CProcess_FatherApp::InitInstance(){AfxEnableControlContainer();#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL #elseEnable3dControlsStatic(); // Call this when linking to MFC statically #endifCProcess_FatherDlg dlg;m_pMainWnd = &dlg;int nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO: Place code here to handle when the dialog is// dismissed with OK}else if (nResponse == IDCANCEL){// TODO: Place code here to handle when the dialog is// dismissed with Cancel}// Since the dialog has been closed, return FALSE so that we exit the// application, rather than start the application's message pump.return FALSE;}Process_FatherDlg.cpp// Process_FatherDlg.cpp : implementation file//#include "stdafx.h"#include "Process_Father.h"#include "Process_FatherDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CProcess_FatherDlg dialogCProcess_FatherDlg::CProcess_FatherDlg(CWnd* pParent /*=NULL*/) : CDialog(CProcess_FatherDlg::IDD, pParent){//{{AFX_DATA_INIT(CProcess_FatherDlg)//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CProcess_FatherDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CProcess_FatherDlg)DDX_Control(pDX, IDC_BT_CreateChildProcess, m_BT_CreateChildProcess);DDX_Control(pDX, IDC_Send, m_Send);DDX_Control(pDX, IDC_LISTBOX_Record, m_LISTBOX_Record);DDX_Control(pDX, IDC_EDIT_Message, m_EDIT_Message);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CProcess_FatherDlg, CDialog)//{{AFX_MSG_MAP(CProcess_FatherDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BT_CreateChildProcess, OnBTCreateChildProcess)ON_BN_CLICKED(IDC_Send, OnSend)//}}AFX_MSG_MAPON_MESSAGE(WM_CHILD_SEND,OnReceiveMsg)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CProcess_FatherDlg message handlersBOOL CProcess_FatherDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control}void CProcess_FatherDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void CProcess_FatherDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags // the minimized window.HCURSOR CProcess_FatherDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CProcess_FatherDlg::OnBTCreateChildProcess(){//创建管道SECURITY_ATTRIBUTES sa;sa.nLength=sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor=NULL;sa.bInheritHandle=TRUE;::CreatePipe(&hPipeRead,&hPipeWrite,&sa,0);::CreatePipe(&hPipeRead2,&hPipeWrite2,&sa,0);//创建子进程STARTUPINFO StartupInfo;memset(&StartupInfo,0,sizeof(STARTUPINFO)) ;StartupInfo.cb=sizeof(STARTUPINFO);StartupInfo.dwFlags=STARTF_USESTDHANDLES;StartupInfo.hStdInput=hPipeRead;StartupInfo.hStdOutput=hPipeWrite;StartupInfo.hStdError=GetStdHandle(STD_ERROR_HANDLE);PROCESS_INFORMATION ProcessInfo;::CreateProcess("Process_Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&Startu pInfo,&ProcessInfo);m_BT_CreateChildProcess.EnableWindow(FALSE);}void CProcess_FatherDlg::OnSend(){CString str;char ss[20]="Father:";m_EDIT_Message.GetWindowText(str);DWORD dwWritten;if(!WriteFile(hPipeWrite,str,40,&dwWritten,NULL)){MessageBox(TEXT("写错误"),"警告",MB_OK|MB_ICONWARNING);}CString strWinName = "Process_Child";CWnd *pWnd=CWnd::FindWindow(NULL,strWinName);if(pWnd){pWnd->SendMessage(WM_FATHER_SEND,0,0);strcat(ss,str);m_LISTBOX_Record.InsertString(-1,ss);m_EDIT_Message.SetWindowText("");}else{MessageBox("没有发现子进程","错误");}}void CProcess_FatherDlg::OnReceiveMsg(WPARAM wParam,LPARAM lParam){DWORD dwRead;TCHAR s[40];HANDLE hPipeRead2;hPipeRead2=GetStdHandle(STD_INPUT_HANDLE);if(!ReadFile(hPipeRead,s,40,&dwRead,NULL)){MessageBox(TEXT("读错误!"),"警告",MB_OK|MB_ICONWARNING);}char str[60]="Child: ";strcat(str,s);m_LISTBOX_Record.InsertString(-1,str);}Process_Father.h// Process_Father.h : main header file for the PROCESS_FATHER application//#if !defined(AFX_PROCESS_FATHER_H__1F9659A2_2B93_4C1E_89C5_5A88971D3DDA__INCLUD ED_)#define AFX_PROCESS_FATHER_H__1F9659A2_2B93_4C1E_89C5_5A88971D3DDA__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#ifndef __AFXWIN_H__#error include 'stdafx.h' before including this file for PCH#endif#include "resource.h" // main symbols///////////////////////////////////////////////////////////////////////////// // CProcess_FatherApp:// See Process_Father.cpp for the implementation of this class//class CProcess_FatherApp : public CWinApp{public:CProcess_FatherApp();// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CProcess_FatherApp)public:virtual BOOL InitInstance();//}}AFX_VIRTUAL// Implementation//{{AFX_MSG(CProcess_FatherApp)// NOTE - the ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_PROCESS_FATHER_H__1F9659A2_2B93_4C1E_89C5_5A88971D3DDA__INCLUDE D_)Process_FatherDlg.h// Process_FatherDlg.h : header file//#if !defined(AFX_PROCESS_FATHERDLG_H__69E2942A_7A5F_413F_B4A3_AFB8C1F51DFE__INC LUDED_)#defineAFX_PROCESS_FATHERDLG_H__69E2942A_7A5F_413F_B4A3_AFB8C1F51DFE__INCLUDED_#define WM_FATHER_SEND WM_USER+100#define WM_CHILD_SEND WM_USER+101#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000///////////////////////////////////////////////////////////////////////////// // CProcess_FatherDlg dialogclass CProcess_FatherDlg : public CDialog{// Constructionpublic:CProcess_FatherDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CProcess_FatherDlg)enum { IDD = IDD_PROCESS_FATHER_DIALOG };CButton m_BT_CreateChildProcess;CButton m_Send;CListBox m_LISTBOX_Record;CEdit m_EDIT_Message;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CProcess_FatherDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CProcess_FatherDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnReceiveMsg(WPARAM wParam, LPARAM lParam);afx_msg void OnBTCreateChildProcess();afx_msg void OnSend();//}}AFX_MSGDECLARE_MESSAGE_MAP()private:HANDLE hPipeWrite2;HANDLE hPipeRead2;HANDLE hPipeWrite;HANDLE hPipeRead;};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before theprevious line.#endif// !defined(AFX_PROCESS_FATHERDLG_H__69E2942A_7A5F_413F_B4A3_AFB8C1F51DFE__INCL UDED_)子进程代码Process_Child.cpp// Process_Child.cpp : Defines the class behaviors for the application.//#include "stdafx.h"#include "Process_Child.h"#include "Process_ChildDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CProcess_ChildAppBEGIN_MESSAGE_MAP(CProcess_ChildApp, CWinApp)//{{AFX_MSG_MAP(CProcess_ChildApp)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSGON_COMMAND(ID_HELP, CWinApp::OnHelp)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CProcess_ChildApp constructionCProcess_ChildApp::CProcess_ChildApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}///////////////////////////////////////////////////////////////////////////// // The one and only CProcess_ChildApp objectCProcess_ChildApp theApp;///////////////////////////////////////////////////////////////////////////// // CProcess_ChildApp initializationBOOL CProcess_ChildApp::InitInstance(){AfxEnableControlContainer();// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL #elseEnable3dControlsStatic(); // Call this when linking to MFC statically #endifCProcess_ChildDlg dlg;m_pMainWnd = &dlg;int nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO: Place code here to handle when the dialog is// dismissed with OK}else if (nResponse == IDCANCEL){// TODO: Place code here to handle when the dialog is// dismissed with Cancel}// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump.return FALSE;}Process_ChildDlg.cpp// Process_ChildDlg.cpp : implementation file//#include "stdafx.h"#include "Process_Child.h"#include "Process_ChildDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CProcess_ChildDlg dialogCProcess_ChildDlg::CProcess_ChildDlg(CWnd* pParent /*=NULL*/): CDialog(CProcess_ChildDlg::IDD, pParent){//{{AFX_DATA_INIT(CProcess_ChildDlg)//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CProcess_ChildDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CProcess_ChildDlg)DDX_Control(pDX, IDC_Send, m_Send);DDX_Control(pDX, IDC_LISTBOX_Record, m_LISTBOX_Record);DDX_Control(pDX, IDC_EDIT_Message, m_EDIT_Message);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CProcess_ChildDlg, CDialog)//{{AFX_MSG_MAP(CProcess_ChildDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_Send, OnSend)//}}AFX_MSG_MAPON_MESSAGE(WM_FATHER_SEND,OnReceiveMsg)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CProcess_ChildDlg message handlersBOOL CProcess_ChildDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control}void CProcess_ChildDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void CProcess_ChildDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags // the minimized window.HCURSOR CProcess_ChildDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CProcess_ChildDlg::OnSend(){char ss[20]="Child:";CString str;m_EDIT_Message.GetWindowText(str);DWORD dwWritten;hPipeWrite=GetStdHandle(STD_OUTPUT_HANDLE);if(!WriteFile(hPipeWrite,str,40,&dwWritten,NULL)) {MessageBox(TEXT("写错误"),"警告",MB_OK|MB_ICONWARNING);}CString strWinName = "Process_Father";CWnd *pWnd=CWnd::FindWindow(NULL,strWinName);if(pWnd){pWnd->SendMessage(WM_CHILD_SEND,0,0);strcat(ss,str);m_LISTBOX_Record.InsertString(-1,ss);m_EDIT_Message.SetWindowText("");}else{MessageBox("没有发现父进程","错误");}void CProcess_ChildDlg::OnReceiveMsg(WPARAM wParam,LPARAM lParam){DWORD dwRead;char s[40];HANDLE hPipeRead;hPipeRead=GetStdHandle(STD_INPUT_HANDLE);if(!ReadFile(hPipeRead,s,40,&dwRead,NULL)){MessageBox(TEXT("读错误!"),"警告",MB_OK|MB_ICONWARNING);}char str[60]="Father: ";strcat(str,s);m_LISTBOX_Record.InsertString(-1,str);}Process_Child.h// Process_Child.h : main header file for the PROCESS_CHILD application//#if !defined(AFX_PROCESS_CHILD_H__7416C60C_DD56_40CC_BD28_3DA310873DE7__INCLUDE#define AFX_PROCESS_CHILD_H__7416C60C_DD56_40CC_BD28_3DA310873DE7__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#ifndef __AFXWIN_H__#error include 'stdafx.h' before including this file for PCH#endif#include "resource.h" // main symbols///////////////////////////////////////////////////////////////////////////// // CProcess_ChildApp:// See Process_Child.cpp for the implementation of this class//class CProcess_ChildApp : public CWinApp{public:CProcess_ChildApp();// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CProcess_ChildApp)public:virtual BOOL InitInstance();//}}AFX_VIRTUAL// Implementation//{{AFX_MSG(CProcess_ChildApp)// NOTE - the ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before theprevious line.#endif// !defined(AFX_PROCESS_CHILD_H__7416C60C_DD56_40CC_BD28_3DA310873DE7__INCLUDED _)Process_ChildDlg.h// Process_ChildDlg.h : header file//#if !defined(AFX_PROCESS_CHILDDLG_H__01C41D47_4973_4DCB_84FC_4B7C5A6C584A__INCL UDED_)#define AFX_PROCESS_CHILDDLG_H__01C41D47_4973_4DCB_84FC_4B7C5A6C584A__INCLUDED_ #define WM_FATHER_SEND WM_USER+100#define WM_CHILD_SEND WM_USER+101#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000///////////////////////////////////////////////////////////////////////////// // CProcess_ChildDlg dialogclass CProcess_ChildDlg : public CDialog{// Constructionpublic:CProcess_ChildDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CProcess_ChildDlg)enum { IDD = IDD_PROCESS_CHILD_DIALOG };CButton m_Send;CListBox m_LISTBOX_Record;CEdit m_EDIT_Message;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CProcess_ChildDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CProcess_ChildDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnReceiveMsg(WPARAM wParam, LPARAM lParam);afx_msg void OnSend();//}}AFX_MSGDECLARE_MESSAGE_MAP()private:HANDLE hPipeWrite;};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_PROCESS_CHILDDLG_H__01C41D47_4973_4DCB_84FC_4B7C5A6C584A__INCLU DED_)。
实验三-进程通信
实验三进程通信一. 实验学时与类型学时:2,课外学时:自定实验类型:设计性实验二. 实验目的了解Linux 的软中断、管道、消息队列、共享存储区等进程间通信方式。
三. 实验内容1. 软中断通信机制(1) 请编写一个程序:循环输出“ how are you? ”,在按下Ctrl+C 后中断显示,输出“ Byebye! ”后退出程序。
#include<signal.h>#include<stdio.h>int k=1;void int_func(int sig) // 软中断处理函数{ k=0; }Int main(){ signal(SIGINT,int_func);// 预置软中断信号处理函数While(k==1) Printf( “ how are you?\n ” );Printf( “ byebye! ” );}I LO w arc y uu? how arc you? h<jw arc you? how arc you? h<)w arc y Ciu? Iw w are you?how arc y on?I LOW arc you? howarc you?h<jw arc you? howarc you?jb y ebye ! [ rOG t <J c a 1 h O s L z zw] # .(2)使用信号机制实现父子进程同步,父进程先输出 #in clude<sig nal.h>#in clude<stdio.h>int k=1;void fun c(i nt sig) { k=0; }main (){ int pid;pid=fork();if(pid>0){ printf( “ A\n ” );kill(pid,12);}else if(pid==0){ sig nal(12,fu nc);while(k==1)sleep(1);printf( “ B\n ”);}}[rao oca Iho s i zzw] , / 12A2. 管道机制(1)父子进程通过管道传送一串字符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三进程通信(二)实验目的:1、理解进程通信原理和基本技术2、了解linux系统进程间通信机构(IPC);3、理解linux关于共享内存的概念;4、掌握linux支持进程间共享内存的系统调用;5、巩固进程同步概念。
实验内容:(一)闹钟。
用c语言编程,实现进程间通过信号进行通信。
用fork()创建两个进程,子进程在等待5秒后用系统调用kill()向父进程发送SIGALRM 信号,父进程用系统调用signal()捕捉SIGALRM信号。
参考程序如下:#include <signal.h>#include <stdio.h>#include <unistd.h>static int alarm_fired = 0; //闹钟未设置//模拟闹钟void ding(int sig){alarm_fired = 1; //设置闹钟}int main(){int pid;printf("alarm application starting\n");if((pid = fork( )) == 0){ //子进程5秒后发送信号SIGALRM给父进程sleep(5);kill(getppid(), SIGALRM);//exit(0);return 0;}//父进程安排好捕捉到SIGALRM信号后执行ding函数printf("waiting for alarm to go off\n");(void) signal(SIGALRM, ding);pause(); //挂起父进程,直到有一个信号出现if (alarm_fired)printf("Ding!\n");printf("done\n");//exit(0);return 0;}调试并运行程序。
观察程序运行结果。
(二)共享内存。
实现利用共享内存机制的生产者/消费者问题的解决方案。
生产者将数据写入共享内存。
消费者从共享内存取出数据,在屏幕输出。
参考如下程序:执行内容说明:1、首先调用shmget()函数建立一块共享内存,大小为1024个字节,该函数返回创建的共享内存标识符。
2、然后调用fork()产生一个子进程(生产者进程)。
子进程调用shmat()函数将该共享内存链接(attach)到自己的虚存空间,即可通过普通的内存写操作(例如strcpy等),在该共享内存写入数据。
3、写完数据后,子进程调用shmdt()函数断开与该共享内存的连接。
4、父进程sleep,直到子进程完成上述操作。
父进程(消费者)调用shmctl()函数得到关于这块共享内存的相关消息,并打印出来。
5、父进程调用shmat()函数将这块共享内存连接到自己的虚存空间,即可以通过普通的内存读操作(例如printf等),将该共享内存中的字符串读出来。
6、读完数据后,父进程调用shmdt()函数断开与该内存的连接。
7、最后,父进程调用shmctl()函数,销毁该共享内存。
#include<unistd.h>#include<sys/ipc.h>#include<sys/shm.h>#include<errno.h>#include <stdio.h>#include <string.h>#define KEY 1234 /*键*/#define SIZE 1024 /*欲建立的共享内存的大小*/int main(){int shmid;char *shmaddr;struct shmid_ds buf;shmid=shmget(KEY,SIZE,IPC_CREAT|0600); /*建立共享内存*/if(shmid==-1){printf("create share memory failed:%s",strerror(errno));return 0;}if(fork( )==0){ /*子进程*/sleep(2);shmaddr=(char*)shmat(shmid,NULL,0); /*系统自动选择一个地址连接*/if(shmaddr==(void*)-1){printf("connect to the share memory failed:%s",strerror(errno));return 0;}/*向共享内存内写数据*/strcpy(shmaddr,"hello,this is shared data.\n");shmdt(shmaddr); /*断开共享内存*///exit(0);return 0;}else{ /*父进程*/wait(0);shmctl(shmid,IPC_STA T,&buf); /*取得共享内存的相关信息*/printf("size of the share memory: shm_segsz=%dbytes\n",buf.shm_segsz);printf("process id of the creator:shm_cpid=%d\n",buf.shm_cpid);printf("process id of the last operator:shm_lpid=%d\n",buf.shm_lpid);shmaddr=(char*)shmat(shmid,NULL,0); /*系统自动选择一个地址连接*/if(shmaddr==(void*)-1){printf("connect the share memory failed:%s",strerror(errno));return 0;}printf("print the content of the share memory:");printf("%s\n",shmaddr);shmdt(shmaddr); /*断开共享内存*//*当不再有任何其它进程使用该共享内存时系统将自动销毁它*/shmctl(shmid,IPC_RMID,NULL);}}调试并运行程序,观察程序是否总能正常运行,并请分析理由。
背景知识1、fork()创建一个新进程int fork()其中返回int取值意义如下:0:创建子进程,从子进程返回的id值大于0:从父进程返回的子进程id值-1:创建失败2、lockf(files,function,size):用作锁定文件的某些段或者整个文件,本函数适用的头文件为:#include<unistd.h>参数定义:int lockf(files,function,size)int files,function;long size;其中:files是文件描述符:function是锁定和解锁;1表示锁定,0表示解锁。
size 是锁定和解锁的字节数,若用0,表示从文件的当前位置到文件尾。
3、msgget(key,flag):获得一个消息的描述符,该描述符指定一个消息队列以便用于其他系统调用。
该函数使用偷文件如下:#include<sy/types.h>#include<sy/ipc.h>#include<sy/msg.h>参数定义int msgget(key,flag)key_tkey;int flag;语法格式:msgqid=msgget(key,flag)其中:msgid是该系统调用返回的描述符,失败则返回-1;flag 本身由操作允许权和控制命令值相“或”得到。
如:IP_CREAT|0400 是否该队列应被创建;IP_EXCL |0400 是否该队列的创建应是互斥的;等。
4、msgsnd(id,msgp,size,flag):发送一消息。
该函数是用头文件如下:#include<sy/types.h>#include<sy/ipc.h>#include<sy/msg.h>参数定义int msgnd(id,msgp,size,flag)int id,size,flag;struct msgbuf * msgp;其中:id是返回消息队列的描述符;msgp是指向用户存储区的一个构造体指针,size指示由msgp指向的数据结构中字符数组的长度;即消息的长度。
这个数组的最大值由MSG-MAX系统可调用参数来确定。
flag规定当核心用尽内部缓冲空间时应执行的动作;若在标志flag中末设置IPC_NOW AIT位,则当该消息队列中字节数超过一最大值时,或系统范围的消息数超过某一最大值时,调用msgsnd进程睡眠。
若是设置IPC_NOW AIT,则在此情况下,msgsnd立即返回。
5、msgrcv(id,msgp,size,type,flag):接受一消息。
该函数调用使用头文件如下:#include<sy/types.h>#include<sy/ipc.h>#include<sy/msg.h>参数定义int msgrcv(id,msgp,size,type,flag)int id,size,type,flag;struct msgbuf * msgq;struct sgbuf{long mtpe;chat mtext[];};语法格式:count=msgrcv(id,msgp,size,type,flag)其中:id是用来存放欲接收消息的拥护数据结构的地址;size是msgp中数据数组的大小;type是用户要读的消息类型:type为0:接收该队列的第一个消息;type为正:接收类型type的第一个消息;type为负:接收小于或等于type绝对值的最低类型的第一个消息。
flag规定倘若该队列无消息,核心应当做什么事,如果此时设置了IPC_NOWAIT 标志,则立即返回,若在flag中设置了MSG_NOERROR,且所接收的消息大小大于size,核心截断所接受的消息。
count是返回消息正文的字节数。
6、msgctl(id,cmd,buf):查询一个消息描述符的状态,设置它的状态及删除一个消息描述符。
调用该函数使用头文件如下:#include<sy/types.h>#include<sy/ipc.h>#include<sy/msg.h>参数定义int msgctl(id,cmd,buf)int id,cmd;struct msgbuf * msgq;struct msqid_ds * buf;其中:函数调用成功时返回0,调用不成功时返回-1。