进程通信实验报告

合集下载

进程间通信实验报告

进程间通信实验报告

进程间通信实验报告班级:10网工三班学生姓名:谢昊天学号:1215134046实验目的和要求:Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。

本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。

实验内容与分析设计:(1)消息的创建,发送和接收。

①使用系统调用msgget (), msgsnd (), msgrev (), 及msgctl () 编制一长度为1k 的消息的发送和接收程序。

②观察上面的程序,说明控制消息队列系统调用msgctl () 在此起什么作用?(2)共享存储区的创建、附接和段接。

使用系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序。

(3)比较上述(1),(2)两种消息通信机制中数据传输的时间。

实验步骤与调试过程:1.消息的创建,发送和接收:(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均退出后结束。

2.共享存储区的创建,附接和断接:(1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。

(2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1。

作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER 每接收到一次数据后显示”(server)received”.(3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT退出. CLIENT每发送一次数据后显示”(client)sent”.(4)父进程在SERVER和CLIENT均退出后结束。

操作系统进程通信报告

操作系统进程通信报告

实验四:进程同步实验一、实验任务:1、熟悉操作系统进程通信原理2、设计程序,实现共享内存、管道通信、消息通信二、实验原理:1、进程间通信的几种方法简介(1)消息队列:消息队列是消息的链接表,包括Posix消息队列systemV消息队列。

有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。

(2)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。

是针对其他通信机制运行效率较低而设计的。

往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

(3)无名管道(Pipe)及有名管道(named pipe):有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;无名管道可用于有亲缘关系的进程之间彼此的通信,进行通信时候必须有一定的机制保证对管道写和读的互斥:即在读是要关闭写的端口,而在写的时候也要保证读的一端是关闭的。

2、进程通信函数(1)消息队列有关系统调用函数a.创建消息队列使用msgget()函数:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int flag) ;该函数成功调用返回消息队列标识符。

其中的key是关键字,可以由ftok()函数得到:key=ftok(“.”,’a’);其中”.”可以是任何目录,’a’是任意字符,即所有群组标识。

flag是标识,IPC_CREAT位表示创建,一般由服务器程序创建消息队列时使用。

如果是客户程序,必须打开现存的消息队列,必须不使用IPC_CREAT。

发送和接收的消息都必须使用一个类似msgbuf的结构表示,msgbuf结构定义如下:struct msgbuf{long mtype;char mtext[1];}上面的定义,消息内容只有一个字节,是不实用的,一般我们需要重新定义一个结构:struct amsgbuf{long mtype;char mtext[200];}其中的mtype都是消息类型。

试验二进程通信Linux试验报告

试验二进程通信Linux试验报告

实验报告学号姓名成绩__________实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。

【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。

它不是用于传输数据,而只是简单地协调对共享资源的访问。

信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。

一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。

当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。

Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。

信号量配置太低会导致Tuxedo系统应用程序无法启动。

2、管道分为两种:管道和命名管道。

管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。

可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。

管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。

后来以管道为基础提出命名管道(namedpipe,FIFO)的概念,该限制得到了克服。

FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。

这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。

值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。

进程通信的实验报告

进程通信的实验报告

一、实验目的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篇)

进程通讯管理实验报告(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操作,实现进程间的同步和互斥。

五、实验结果通过实验,我们成功实现了进程的创建、调度和终止,以及进程间的信息传递和同步管理。

实验二进程通信 Linux实验报告

实验二进程通信 Linux实验报告

实验报告学号_____ 姓名____ ___ 成绩实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。

【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。

它不是用于传输数据,而只是简单地协调对共享资源的访问。

信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。

一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。

当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。

Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。

信号量配置太低会导致Tuxedo系统应用程序无法启动。

2、管道分为两种:管道和命名管道。

管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。

可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。

管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。

后来以管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服。

FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。

这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。

值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。

实验一 进程通信操作系统实验报告

实验一 进程通信操作系统实验报告




2.用pipe()创建一个管道,然后用fork()创建两个生产进程和两个消费进程,它们之间能过pipe()传递信息。


结果
遇到问题及解决方法
int i,pid,status;
for(i=0;i<4;i++) pid=wait(*status); i,pid,status;


结果
遇到问题及解决方法
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*&arg);此语句void*后缺少),正确语句应为:
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*)&arg);
for(i=0;i<4;i++) pid=wait(&status);
if(id==1) stcopy(w_buf,"ccc\0");
else strcpy(w_buf,"ddd\0");
此语句中stcopy词语写错,应改为strcpy,即
if(id==1) strcpy(w_buf,"ccc\0");
学年第学期
操作系统课程
实验报告
学院:
专业:
班级:
姓名:
学号:
任课教师:
实验日期:2017年4月11日
实验题目
实验一进程通信
实验地点
实验目的
1.理解Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据的过程。

操作系统实验报告 进程通信

操作系统实验报告    进程通信
Char outpipe[100],inpipe[100];
Pipe(fd);
While ((pid1=fork())==-1;
If (pid1==0)
{
Printf(“child 1 will going on!\n”);
Lockf(fd[1],1,0);
Sprintf(outpipe,”child 1 process is sending message!”);
西北师范大学计算机科学与工程学院学生实验报告
学号
专业
计算机科学与技术
姓名
课程名称
操作系统实验
班级
2011级计师(1)班
实验名称
实验五进程通信
课程类型
必修类
一.实验目的:
(1)了解Linux系统中进程通信的基本原理;
(2)了解和掌握管道通信机制;
(3)了解和熟悉消息通信机制、共享存储区机制以及信号通信机制。
Wait(0);
Read(fd[0],inpipe,50);
Printf(“%s\n”,inpipe);
Exit(0);
}
}
}
四.分析分析实验结果
功能:使用系统调用pipe()建立一条管道线,两个子进程p1和p2分别向管道各写一句话,而父进程从管道中读出来自于两个子进程的信息,显示在屏幕上。
说明:Lockf(files,function,size)
二.实验内容
1.编写一段程序,实现进程的管道通信。
使用系统调用pipe( )建立一条管道,创建两个子进程P1和P2。让P1和P2分别向管道各写一句话:
Child 1 is sending a message!
Child 2 is sending a message!

Linux进程通信实验报告

Linux进程通信实验报告

三、 实验环境
一台安装了 Red Hat Linux 9 操作系统的计算机。
四、 实验操作方法和步骤
进入 Linux 操作系统,利用 vi 编辑器将程序源代码输入并保存好,然后 打开终端对程序进行编译运行。
五、 实验中遇到的问题及解决 六、 实验结果及分析
基本实验
可选实验
七、 源代码
Pipe.c #include"stdio.h" #include"unistd.h" main(){ int i,j,fd[2]; char S[100]; pipe(fd); if(i=fork==0){ sprintf(S,"child process 1 is sending a message \n"); write(fd[1],S,50); sleep(3); return; } if(j=fork()==0){ sprintf(S,"child process 2 is sending a message \n"); write(fd[1],S,50); sleep(3); return;
}else{ wait(0); read(fd[0],S,50); printf("%s",S); read(fd[0],S,50); printf("%s",S); return; } } Softint.c #include"stdio.h" #include"unsitd.h" main(){ int i,j,fd[2]; char S[100]; pipe(fd); if(i=fork==0){ sprintf(S,"child process 1 is sending a message \n"); write(fd[1],S,50); sleep(3); return; } if(j=fork()==0){ sprintf(S,"child process 2 is sending a message \n"); write(fd[1],S,50); sleep(3); return; }else{ wait(0); read(fd[0],S,50); printf("%s",S); read(fd[0],S,50); printf("%s",S); return;}Leabharlann }Linux 进程通信实验报告

进程通信实验报告

进程通信实验报告

操作系统实验报告(三)进程通信专业:软件工程姓名:XXX班级:XXX学号:XXX指导老师:XXX2013/12/3实验三:进程通信一.实验目的加深对进程通信的理解。

熟悉消息通信机制、共享存储器通信机制,进一步认识其与信号量通信的区别。

二.实验内容1)编程实现基于消息缓冲队列机制的进程通信数据结构和通信原语(创建消息、发送消息、接收消息);2)最后编写主函数对所做工作进行测试三.实验步骤(1)任务分析:实现进程通信,需要建立创建消息函数、发送消息函数、接收消息函数,需要用到进程中的Send和Receive原语(2)程序设计:a.总体设计:创建两个windows窗体应用程序,分别用于发送消息和接收消息,可以采用C#实现。

b.具体实现①创建应用程序Sendmessage,在windows窗体上放置一个文本框输入要发送的消息,一个按钮控件,单击按钮控件发送消息,编辑ButtonOnclick()事件,来编辑发送消息函数,发送后弹出消息发送成功对话框。

②创建应用程序Receivemessage,在windows窗口上放置一个文本框用于接收消息,放置一个Button按钮,并编辑ButtonOnclick()事件,来编辑接收消息函数,成功后弹出成功接收对话框。

③程序中的发送接收需要用到系统中的函数,将在实验代码中给与提示。

(4)调试与测试实验结果:发送消息:接收消息:四.实验总结进程通信实验主要是通过通信原语机制创建消息发送函数和消息接收函数来模拟实现进程间的通信,在实验过程中,一些通信机制不是太明确,通过在网上查找资料以及和同学们交流,最终完成了进程通信实验,通过这次实验,我对进程间的通信原理多了更深一步的了解,为学习操作系统知识建立了良好的实践基础。

五.附录①发送消息函数源码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form1(){InitializeComponent();}[DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(int hWnd,int Msg,int wParam,ref COPYDATASTRUCT lParam);[DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern int FindWindow(string lpClassName, string lpWindowName);public struct COPYDATASTRUCT{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}const int WM_COPYDATA = 0x004A;private void button1_Click(object sender, EventArgs e){Sent();MessageBox.Show("信息发送成功|", "提示?", MessageBoxButtons.OK);}private void Sent(){int WINDOW_HANDLER = FindWindow(null, @"接受信息");if (WINDOW_HANDLER != 0){byte[] sarr =System.Text.Encoding.Default.GetBytes(this.textBox1.Text);int len = sarr.Length;COPYDATASTRUCT cds;cds.dwData = (IntPtr)100;cds.lpData = this.textBox1.Text;cds.cbData = len + 1;SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds); } }}}②接收消息函数源码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApplication2{public partial class Form1 : Form{string message;public Form1(){InitializeComponent();}public struct COPYDATASTRUCT{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}const int WM_COPYDATA = 0x004A;private void button1_Click(object sender, EventArgs e) {Receive();}private void Receive(){textBox1.Text += "收到信息为"+ message + Environment.NewLine;MessageBox.Show("成功接收!");}protected override void DefWndProc(refSystem.Windows.Forms.Message m){switch (m.Msg){case WM_COPYDATA:COPYDATASTRUCT mystr = new COPYDATASTRUCT();Type mytype = mystr.GetType();mystr = (COPYDATASTRUCT)m.GetLParam(mytype); message = mystr.lpData;break;default:base.DefWndProc(ref m);break;}}}}。

实验三_进程间的通信

实验三_进程间的通信

本科实验报告专用纸课程名称操作系统原理成绩评定实验项目名称进程间的通信指导教师实验项目编号实验项目类型实验地点学生姓名学号学院系专业实验时间年月日上午~月日上午温度℃湿度一、实验目的和要求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. 分析2.1 实验要求本次实验要求我们编写一个进程控制与进程通信程序,实现以下功能:1.创建一个主进程和多个子进程,并实现进程的执行和切换;2.子进程之间通过进程通信机制传递信息;3.实现多个子进程之间的协作,完成指定的任务。

2.2 系统设计为了满足实验的要求,我们可以按照以下步骤设计我们的系统:1.创建主进程和多个子进程:使用操作系统提供的进程创建函数,创建一个主进程和多个子进程。

主进程将负责协调子进程的执行和协作。

2.进程执行和切换:使用操作系统提供的进程执行和切换函数,实现进程的执行和切换操作。

主进程可以通过改变进程的状态和优先级来控制进程的执行和切换。

3.进程通信机制:使用操作系统提供的进程通信机制,如消息队列、共享内存等,实现子进程之间的信息传递。

可以定义统一的消息格式,并使用相应的函数进行消息的发送和接收。

4.进程协作:根据实验要求,设计子进程之间的协作方式。

可以使用信号量、条件变量等机制来实现多个子进程之间的同步和互斥。

2.3 实验结果实验的结果将是一个能够创建多个子进程,并通过进程通信进行协作的程序。

程序将实现以下功能:1.主进程创建多个子进程,并通过改变进程的状态和优先级来控制进程的执行;2.子进程通过进程通信机制传递信息,完成指定的任务;3.子进程之间通过协作实现同步和互斥,保证任务的正确执行。

3. 实验步骤3.1 创建进程首先,我们需要创建主进程和多个子进程。

进程通信报告

进程通信报告

进程间的通信1.引言在W in dows程序中,各个进程之间常常需要交换数据,进行数据通讯。

WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换.内部进程间通讯和数据交换有多种方式:消息、共享内存、命名管道、邮槽、Windows 套接字等多种技术。

“共享内存”(shared memory)可以定义为对一个以上的进程是可见的内存或存在于多个进程的虚拟地址空间。

例如:如果两个进程使用相同的DLL,只把DLL的代码页装入内存一次,其他所有映射这个DLL的进程只要共享这些代码页就可以了;利用消息机制实现IP C虽然有交换的数据量小、携带的信息少等缺点,但由于其实现方便、应用灵活而广泛应用于无须大量、频繁数据交换的内部进程通讯系统之中。

本文通过共享内存实现进程间的数据交换,利用windows消息机制实现进程间的同步,两种机制结合使用,不仅解决了交换数据量小的问题,还解决了进程并发存取数据的问题。

2.提出问题1.1问题:2个进程怎么通过共享内存来数据交换1.2 问题:2个进程间怎么利用消息机制实现信息通信3.解决方案3.1利用消息实现内部进程通讯1.创建和访问一个消息队列格式:int msgget(key_t key,int msgflag);返回值为对应消息的描述符(整型常量)。

2.发送消息(把一条消息添加到消息队列中去)格式:int msgsnd(int msqid,const void *smg_ptr,size_t msg_sz,int msgflag); 3.接收消息格式:int msgrcv(int msqid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflag);4.控制和删除消息格式:int msgctl(int msqid,command,function);注意:msgsnd()和msgrcv()和msgctl()命令若执行成功,则返回0,若不成功,则返回-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_)。

进程通信实验报告

进程通信实验报告

进程通信实验报告进程通信实验报告概述进程通信是操作系统中非常重要的一个概念,它允许不同的进程之间进行数据的交换和共享。

在本次实验中,我们通过使用不同的进程通信机制,如管道、消息队列和共享内存,来实现进程之间的数据传输和通信。

本报告将详细介绍实验的背景、实验过程、结果分析以及对实验的总结。

实验背景进程通信是操作系统中的一个核心概念,它允许多个进程之间进行数据的交换和共享。

在现代操作系统中,进程通信是实现并发和协作的重要手段。

了解不同的进程通信机制以及它们的优缺点对于深入理解操作系统的原理和实现至关重要。

实验过程在本次实验中,我们使用了三种不同的进程通信机制:管道、消息队列和共享内存。

首先,我们创建了两个进程,一个作为发送方,一个作为接收方。

然后,我们分别使用了管道、消息队列和共享内存来实现进程之间的数据传输和通信。

管道是一种最简单的进程通信机制,它可以在父进程和子进程之间进行单向的通信。

我们通过创建一个管道,并将其连接到父进程和子进程的标准输入和标准输出,实现了父子进程之间的数据传输。

消息队列是一种更为灵活的进程通信机制,它可以实现多个进程之间的双向通信。

我们使用了系统提供的消息队列函数,创建了一个消息队列,并在发送方将消息发送到队列中,接收方则从队列中接收消息。

通过消息队列,我们实现了进程之间的异步通信。

共享内存是一种高效的进程通信机制,它允许多个进程共享同一块内存空间。

我们使用了共享内存函数,创建了一个共享内存区域,并将其映射到两个进程的虚拟地址空间中。

通过共享内存,我们实现了进程之间的数据共享和同步。

结果分析通过实验,我们发现不同的进程通信机制各有优缺点。

管道是最简单的一种机制,但只能实现单向通信,且只能用于具有亲缘关系的进程。

消息队列可以实现多个进程之间的双向通信,但消息的顺序可能会被打乱。

共享内存是最高效的一种机制,但需要额外的同步机制来保证数据的一致性。

总结进程通信是操作系统中非常重要的一个概念,它允许不同的进程之间进行数据的交换和共享。

实验三 进程通信 实验报告

实验三 进程通信 实验报告
waiting( );
lockf(stdout,1,0);
printf("Child process 1 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}
void waiting( )
{
while(wait_mark!=0);
}
void stop( )
(2)pid=0时,核心将信号发送给与发送进程同组的所有进程。
(3)pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。
2、signal( )
预置对信号的处理方式,允许调用进程控制软中断信号。
系统调用格式
signal(sig,function)
头文件为
#include <signal.h>
wait(0);
printf("Parent process is killed!\n");
exit(0);
}
else
{
wait_mark=1;
signal(SIGINT,stop);
signal(17,stop); /*接收到软中断信号17,转stop*/
waiting( );
lockf(stdout,1,0);
printf("Child process 2 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(SIGINT,stop);
signal(16,stop);/*接收到软中断信号16,转stop*/

操作系统程序进程通信实验报告详解

操作系统程序进程通信实验报告详解

进程通信指导老师:夏建一、实验题目进程通信上机实验(消息缓冲通信)二、算法思想1、在进程管理(调度)实验基础上,加入进程通信的功能,采用消息缓冲通信机制进行通信。

2、P1发送数据给P2,P2排序后发送给P3,P3接收数据并输出。

3、要发送的数据内容由操作者实时输入。

三、小组分工:四、算法程序1、缓冲区结构typedef struct node{int id;int size;char text[100];struct node *next;}buftype;2、进程控制块PCBstruct {int id;char status;int waiter1;int priority;char stack[5];int sm;buftype *front;buftype *rear;}pcb[4];3 .发送、接收、排序程序算法流程(1)发送函数 send()分配缓冲区空间,由P指向接收进程标识符、信息长度存入缓冲区置链接指针为空,将信息正文从发送区复制到正文区队尾指针指向新插入缓冲区队列缓冲区个数计数加1程序:void send(int rec_id,char a[],int n){buftype *p;p=(buftype *)malloc(sizeof(buftype));p->id=rec_id; //接收消息进程idp->size=n; //消息的大小strcpy(p->text,a); //将消息拷贝到节点之中p->next=0;if(pcb[rec_id].sm<=0)//如果消息缓冲队列空..就将p放在链首{pcb[rec_id].front=p;}elsepcb[rec_id].rear->next=p;//如果不空..放在队尾..rear 指针后移一位pcb[rec_id].rear=p;//队尾指针指向新加入的缓冲区 pcb[rec_id].sm++; //接收进程的消息个数+1}(2)接收函数 receive ()调用参数:rec_id 接收进程标识符输出“无消息”提示信息,返回 复制数据到接收区数组b释放缓冲区程序:int receive(int rec_id,char b[]){buftype *p;if(pcb[rec_id].sm<=0){printf("no message!!\n");return 0;}else{p=pcb[rec_id].front;pcb[rec_id].sm--;pcb[rec_id].front=pcb[rec_id].front->next;//取出来后..front指针后移一位strcpy(b,p->text);free(p);if(pcb[rec_id].front==NULL)pcb[rec_id].rear=NULL;return 1;}}(3)排序函数 sort()调用参数:a[ ] 待排序数组,n 数据个数;程序:void sort(char a[],int n){int i,j;char temp;for(i=0;i<n;i++){for(j=i+1;j<n;j++){if(a[j]<a[i]){temp=a[i];a[i]=a[j];a[j]=temp;}//if}//for}}a 数组 100字符) len P22.修改P1、P2、P3程序Process1() 在阻塞前插入以下操作代码Process1() 在阻塞前插入以下操作提示用户输入选择字符b 数组 P3 a 数组 字符)lenP2Process1程序:process1(){char flag;char a[100];int len;if(addr=='m') goto m;i=1;m1=1;a: printf("\n process1 printing m1=%d\n\n",m1);printf("do you want to send data ?(y/n)"); //是否发送消息flag=getchar();if(flag=='y'||flag=='Y'){printf("input data:");scanf("%s",a);len=strlen(a);send(1,a,len); //将消息输送到缓冲队列中printf("\n");}printf("process1 calls p on sem1!\n");if(p(1,1,'m')==0)return (0);m: printf("\n=>process1 i=%d\n\n",i);i=i+5;goto a;}Process2程序:process2(){char flag;char b[100];int len;if(addr=='m') goto m;if(addr=='n') goto n;i=1;a: printf("\n process2 printing m1=%d\n",m1);m2=2*m1;printf("do you want to receive message?(y/n)");//是否接收消息getchar();flag=getchar();if(flag=='y'||flag=='Y'){if(receive(1,b)==0){ //消息队列为空getchar();}else{ //打印接收的消息,并且排序printf("\n%s\n\n",b);len=strlen(b);sort(b,len);printf("\n%s\n\n",b);send(2,b,len);}}printf("process2 call p on sem2\n");if(p(2,2,'m')==0)return (0);m: printf("process2 call v on sem1!\n");if(v(1,2,'n')==0)return (0);n: printf("\n=>process2 i=%d\n\n",i);i=i+10;goto a;}Process3()在P3调用V 操作唤醒P2前加入以下操作Process3程序:process3(){char c[100];if(addr=='m') goto m;if(addr=='n') goto n;i=1;a: printf("\n=>process3 i=%d\n",i);if(i>=num) goto b;printf("\n process3 printing 2^i=%d\n\n",m2);m1=m2;if(receive(2,c)){printf("==>SORT RESULT:%s\n\n",c);getchar();}else{printf("==>SORT RESULT:\n\n");getchar();}getchar();printf("process3 call v on sem2!\n"); 调用接收函数,接收数据送到接收区c 数组 输出接收区数据if(v(2,3,'m')==0) return (0);m: i++;goto a;b: if(receive(2,c)){printf("==>result:%s\n\n",c);getchar();}else{printf("==>result:\n\n");getchar();}printf("\nprocess3 calls p on sem2\n"); if(p(2,3,'n')==0) return (0);n: ;}四、测试情况、分析下面的是调试正确后的程序结果:(1)发送后立刻接受:(2)接下来三个进程五、收获与体会经过这次的实验,我收获良多,同时也让我明白,动手了,实践了就有希望,就会有希望完成任务。

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

操作系统实验报告(三)
进程通信
专业:软件工程
姓名:XXX
班级:XXX
学号:XXX
指导老师:XXX
2013/12/3
实验三:进程通信
一.实验目的
加深对进程通信的理解。

熟悉消息通信机制、共享存储器通信机制,进一步认识其与信号量通信的区别。

二.实验内容
1)编程实现基于消息缓冲队列机制的进程通信数据结构和通信原语(创建消息、发送消息、接收消息);
2)最后编写主函数对所做工作进行测试
三.实验步骤
(1)任务分析:实现进程通信,需要建立创建消息函数、发送消息函数、接收消息函数,需要用到进程中的Send和Receive原语
(2)程序设计:
a.总体设计:创建两个windows窗体应用程序,分别用于发送消息和接收消息,可以采用C#实现。

b.具体实现
①创建应用程序Sendmessage,在windows窗体上放置一个文本框输入要发送
的消息,一个按钮控件,单击按钮控件发送消息,编辑ButtonOnclick()事件,来编辑发送消息函数,发送后弹出消息发送成功对话框。

②创建应用程序Receivemessage,在windows窗口上放置一个文本框用于
接收消息,放置一个Button按钮,并编辑ButtonOnclick()事件,来编辑接收消
息函数,成功后弹出成功接收对话框。

③程序中的发送接收需要用到系统中的函数,将在实验代码中给与提示。

(4)调试与测试
实验结果:
发送消息:
接收消息:
四.实验总结
进程通信实验主要是通过通信原语机制创建消息发送函数和消息接收函数来模拟实现进程间的通信,在实验过程中,一些通信机制不是太明确,通过在网上查找资料以及和同学们交流,最终完成了进程通信实验,通过这次实验,我对进程间的通信原理多了更深一步的了解,为学习操作系统知识建立了良好的实践基础。

五.附录
①发送消息函数源码:
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(
int hWnd,
int Msg,
int wParam,
ref COPYDATASTRUCT lParam
);
[DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern int FindWindow(string lpClassName, string lpWindowName);
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
const int WM_COPYDATA = 0x004A;
private void button1_Click(object sender, EventArgs e)
{
Sent();
MessageBox.Show("信息发送成功|", "提示?", MessageBoxButtons.OK);
}
private void Sent()
{
int WINDOW_HANDLER = FindWindow(null, @"接受信息");
if (WINDOW_HANDLER != 0)
{
byte[] sarr =
System.Text.Encoding.Default.GetBytes(this.textBox1.Text);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = this.textBox1.Text;
cds.cbData = len + 1;
SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds); } }}}
②接收消息函数源码:
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
string message;
public Form1()
{
InitializeComponent();
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
const int WM_COPYDATA = 0x004A;
private void button1_Click(object sender, EventArgs e) {
Receive();
}
private void Receive()
{
textBox1.Text += "收到信息为"+ message + Environment.NewLine;
MessageBox.Show("成功接收!");
}
protected override void DefWndProc(ref
System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT)m.GetLParam(mytype); message = mystr.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
}。

相关文档
最新文档