实验9 进程间管道通信实验

合集下载

进程的管道通信实验说明书

进程的管道通信实验说明书

*******************实践教学*******************兰州理工大学计算机与通信学院2011年秋季学期操作系统原理课程设计题目:进程的管道通信实验专业班级:09软件工程(1)班姓名:刘旭学号:09240201指导教师:王旭阳成绩:_______________目录摘要 (3)正文 (4)一.问题描述 (4)二. 设计目的 (4)三. 设计要求 (5)四. 详细设计 (5)1.程序流程图 (6)2.算法设计 (7)五. 结果分析 (9)设计总结 (10)参考文献 (11)致谢 (12)附件Ⅰ源程序代码 (13)摘要管道通信是发送进程和接收进程之间通过一个通道交流信息,管道是单向的,发送进程视管道为输出文件,即向管道写入数据,接收进程视管道为输入文件,即从中读取数据。

先写入的必定先读出,即管道通信的工作是单向的并以先进先出为顺序。

管道通信的实质是一个共享文件,数据以自然字符流的方式写入和读出。

在Linux系统中,进程在执行系统调用pipe()之后便创建了一个无名管道。

在管道通信实验中,可用父进程创建一个无名管道,子进程向其中写入信息,父进程从其中读取信息并显示。

关键词:父进程,子进程,管道,通信,文件正文一.问题描述:(1).了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,练习并掌握UNIX提供的vi编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序。

(2).编写程序实现进程的管道通信。

用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。

二.设计目的:通过该题目的设计过程,熟悉UNIX/LINUX支持的管道通信方式,了解该系统下进程管道通信机制,掌握进程管道通信程常用的系统函数,能够编写代码实现父子进程的管道通信。

进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验3 Linux 进程间通信一、软中断信号的处理,实现同一用户的各进程之间的通信。

●相关的系统调用⏹kill(pid ,sig):发送信号⏹signal(sig, func):指定进程对信号sig的处理行为是调用函数func。

●程序清单#include <unistd.h>#include <stdio.h>#include <signal.h>void waiting();void stop();int wait_mark;main(){int p1,p2;while((p1=fork())==-1);if(p1>0){while((p2=fork())==-1);if(p2>0){ printf("parent\n");/*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。

这里省略。

*/kill(p1,16);kill(p2,17);wait(0);wait(0);printf("parent process id killed! \n");exit(0);}else/* p2==0*/{printf("p2\n");wait_mark=1;signal(17,stop);waiting();printf("child process 2 is killed by parent! \n");exit(0);}}else/*p1==0*/{printf("p1\n");wait_mark=1;signal(16,stop);waiting();printf("child process 1 is kelled by parent! \n");exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}●输入并运行此程序,分析程序的运行结果。

操作系统实验报告(进程的管道及消息通信)

操作系统实验报告(进程的管道及消息通信)
if(argc==2) {
printf("\n Ihave wrote:%s",string); write(fd,string,45); string[0]+=1; } else { read(fd,buf,256); printf("\n The context by I have read is :!%s",buf); buf[0]='\0'; } } close(fd); } 运行结果:
char parent[]="A message to pipe'communication.\n";
main() {
int pid,chan1[2]; char buf[100]; pipe(chan1); pid=fork(); if(pid<0) {
printf("to create child error\n"); exit(1); } if(pid>0) { close(chan1[0]); printf("parent process sends a message to child.\n"); write(chan1[1],parent,sizeof(parent)); close(chan1[1]); printf("parent process waits the child to terminate\n"); wait(0); printf("parent process terminate\n"); } else { close(chan1[1]); read(chan1[0],buf,100); printf("The message read by child process from parent is :%s.\n",buf); close(chan1[0]); printf("child process terminates\n"); } } 运行结果:

操作系统实验报告进程的管道及消息通信

操作系统实验报告进程的管道及消息通信

运行结果如下:结果分析:父进程首先被调用时,运行结果为:之后父进程阻塞等待子进程终止,当系统调度子进程运行时,输出如下的信息:之后父进程被唤醒,调度运行,输出如下结果后程序退出。

对于以上的结果:首先父进程使用pipe(chan1)系统调用打开一个无名管道,之后创建一个子进程。

子进程复制父进程的打开文件表。

为了正确通信,父进程关闭读通道close(chan1[0]),子进程关闭写通道close(chan1[1])。

父进程向管道写,子进程从管道读。

完成一次通信之后,父进程分别关闭自己的写/读通信,管道文件消失。

2.以命名行为参数的管道文件的示例。

(假设有一个可执行程序chcase,从标准输入设备读字符,将小写字母转化成大写字母并输出。

主程序使用popen创建管道,实现蒋某文本文件中的字幕转化成大写字母,其中的文本文件名作为参数传进来。

)编写的程序如下:运行结果是:结果分析:通过程序运行结果可知,先打开文本文件,如果文本打开失败,则执行exit(1),退出程序,如果文本通过函数开成功,则popen 创建一个可写管道,将命令行chcase的输入与管道的输入连接起来,然后向管道输入数据,此时命令行就可以通过管道接受文本文件的数据了,在从文件中读出数据时,独处的内容放在line[]数组中,fpin表示从刚打开的文件里读出。

之后要编写字母大小写转化函数,来实现小写字母转化成大写字母。

3.创建有名管道。

编写的程序如下:运行结果是:前台运行结果:后台运行结果:结果分析:此程序是把管道和命令联系起来,read( )的系统调用格式是read(fd,buf,n),参数定义是int read(fd,buf,n); int fd; char *buf; unsigned n;它的功能是从fd所指示的文件中读出n个字节的数据,并将它们送至由指针buf所指示的缓冲区中。

如该文件被加锁,等待,直到锁打开为止;write( )系统调用格式是read(fd,buf,n),它的功能是把n个字节的数据,参数定义同read( ),而父进程则从管道中读出来自两个进程的信息,显示在屏幕上。

进程通信的实验报告

进程通信的实验报告

一、实验目的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. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。

进程间通信实验.docx

进程间通信实验.docx

进程间通信实验8000114134 欧阳为软工143Q1:使用无名管道pipe(),进行父子进程之间的通信。

A1:截图如下:分析:这段程序使用匿名管道,实现了同一进程组(父子进程间)的通信。

首先父进程使用函数pipe( )创建一个匿名管道,chan1[ ]被填入两个文件描述符,在该程序中chan[0]负责读操作,chan[1]负责写操作;创建匿名管道之后使用fork( )创建子进程,由于匿名管道是半双工的,即数据只能向一个方向流动,父进程写入数据,子进程读出,如果子进程一直不读出数据,写操作就会阻塞;程序为了保证正确通信,在父进程执行写操作时关闭读管道(close(chan1[0]));子进程读期间,关闭写管道。

Q2:以命名行为参数的管道文件的示例。

(假设有一个可执行程序chcase,从标准输入设备读字符,将小写字母转化成大写字母并输出。

主程序使用popen创建管道,实现蒋某文本文件中的字幕转化成大写字母,其中的文本文件名作为参数传进来。

)A2:截图如下:分析:在执行该程序之前,首先编译完成字符串大小写转变程序chcase以及文本文件chcase.txt。

在执行该程序时,文本文件需要作为参数传入;程序首先使用fopen()打开文本文件,若文本文件存在打开成功,则使用popen( )函数打开一个管道,popen( )函数用创建管道的方式启动一个进程,又因为管道是单向的,所以其type 参数只能定义成只读或者只写,如图:启动进程为只写,此时popen( )创建了一个只写管道,将命令行chcase 的输入与管道的输入连接,向管道输入数据,进程chcase 读出数据并将数据转化为大写。

Q3:创建有名管道A3:截图如下:分析:使用mknod()创建一个命名管道fifo,第一个参数是要创建的管道名,第二个参数指文件类型,第三个参数指设备号(普通文件设备号为0),命名管道遵循先进先出原则。

当输入命令的参数小于2时,进程为读数据而打开命名管道,而在之前并未因为写操作而打开管道,即管道中并没有数据,所以进程阻塞;输入命令参数等于2 ,进程打开管道写入数据,将字符串string的数据写入fifo 文件,最后输入小于2的命令行参数,进程读数据并输出。

进程的管道通信实验报告

进程的管道通信实验报告

进程的管道通信实验报告一、实验目的本实验旨在通过实际操作,深入理解进程间通信(IPC)的原理,掌握管道通信的实现方法,提高对操作系统进程管理的理解。

二、实验环境实验环境为Linux操作系统,使用Shell脚本进行进程的管道通信实验。

三、实验内容1. 创建两个Shell脚本文件,分别命名为sender.sh和receiver.sh。

2. 在sender.sh中,编写一个简单的程序,用于向管道中写入数据。

程序包括一个无限循环,每次循环中随机生成一个数字并写入管道。

3. 在receiver.sh中,编写一个简单的程序,用于从管道中读取数据。

程序同样包括一个无限循环,每次循环中从管道中读取一个数字并输出。

4. 使用Shell命令将sender.sh和receiver.sh链接起来,实现进程间的管道通信。

四、实验过程1. 打开两个终端窗口,分别用于运行sender.sh和receiver.sh。

2. 在第一个终端窗口中,输入命令“bash sender.sh”运行sender.sh脚本。

该脚本将创建一个无限循环,每次循环中随机生成一个数字并写入管道。

3. 在第二个终端窗口中,输入命令“bash receiver.sh”运行receiver.sh脚本。

该脚本将创建一个无限循环,每次循环中从管道中读取一个数字并输出。

4. 观察两个终端窗口的输出,可以看到sender.sh进程向管道中写入的数字被receiver.sh进程读取并输出。

五、实验总结通过本次实验,我们成功实现了进程间的管道通信。

在实验过程中,我们深入了解了进程间通信的原理和实现方法,掌握了管道通信的基本操作。

通过实际操作,我们更好地理解了操作系统中进程管理、进程间通信的相关知识。

同时,我们也发现了一些不足之处,例如在程序中没有添加异常处理机制等。

在今后的学习中,我们将继续深入探索进程间通信的相关知识,提高自己的编程技能和系统设计能力。

实现进程间通信的实验原理

实现进程间通信的实验原理

实现进程间通信的实验原理进程间通信(Inter-Process Communication,IPC)是指在操作系统中,不同的进程之间进行数据交换和共享的一种机制。

常见的进程间通信的方法有:1. 管道(Pipe):管道是一种半双工的通信机制,它可以实现父子进程之间的通信。

通常由操作系统创建,父进程创建一个管道后,可以通过fork系统调用创建子进程,从而共享管道。

子进程可以通过管道进行写入一端,父进程可以通过管道进行读取。

2. 命名管道(Named Pipe):命名管道也是一种管道,但它允许不相关的进程之间进行通信。

命名管道被创建时,通过指定一个路径名,从而使不同进程能够通过路径名来访问同一管道。

3. 信号量(Semaphore):信号量是一种计数器,用于控制多个进程对共享资源的访问。

进程可以通过特定的操作(比如P操作和V操作)来对信号量进行增加或减少操作。

同一时刻只允许一个进程对信号量进行P操作,其他进程需要等待。

4. 共享内存(Shared Memory):共享内存是一种进程之间共享数据的方式,它在物理内存中创建一块共享区域,多个进程可以将这块内存映射到各自的虚拟地址空间中。

进程可以直接读写共享内存,而无需进行数据拷贝。

5. 消息队列(Message Queue):消息队列是一种可以实现不同进程之间通过消息进行通信的机制。

进程可以通过特定的操作将消息发送到消息队列中,其他进程可以从消息队列中读取消息。

6. 套接字(Socket):套接字是一种网络编程中常用的进程间通信方式。

它可以在不同主机上的进程之间进行通信。

进程可以通过套接字进行网络数据的读取和写入。

以上是常见的几种进程间通信的方法,每种方法都有自己的优势和适用场景。

根据具体的需求,可以选择适合的方式进行进程间通信。

进程的管道通信实验总结

进程的管道通信实验总结

进程的管道通信实验是一个非常有用的实验,它允许两个进程之间进行数据交换。

这个实验主要涉及到了管道、管道缓冲区以及进程之间的通信机制。

以下是对这个实验的总结:
1. 管道的概念和作用:
管道是一种用于进程间通信的机制,它允许两个进程之间进行数据交换。

在管道通信实验中,我们创建了一个管道,并使用它来在两个进程之间传递数据。

管道的作用是连接两个进程,使得它们可以相互发送和接收数据。

2. 管道缓冲区:
管道缓冲区是管道中的一个重要概念。

当一个进程向管道写入数据时,数据会被写入缓冲区中,等待另一个进程读取。

当缓冲区中的数据被读取后,缓冲区中的数据会被移除,为新的数据腾出空间。

3. 进程间的通信:
在管道通信实验中,我们创建了两个进程,并使用管道来在它们之间进行通信。

一个进程向管道写入数据,另一个进程从管道读取数据。

通过这种方式,两个进程可以相互发送和接收数据。

4. 实验中的问题和解决方案:
在实验中,我们遇到了一些问题,如管道中的数据读写错误、进程间的通信问题等。

为了解决这些问题,我们采取了一些措施,如检查数据的读写是否正确、确保进程间的通信畅通等。

5. 实验的意义和收获:
通过这个实验,我们深入了解了进程间通信的概念和机制,并掌握了管道通信的基本原理和方法。

此外,我们还学会了如何解决实验中遇到的问题,提高了我们的编程能力和解决问题的能力。

总之,进程的管道通信实验是一个非常有意义的实验,它让我们深入了解了进程间通信的原理和方法。

通过这个实验,我们不仅掌握了相关的知识和技能,还提高了我们的编程能力和解决问题的能力。

进程通信-管道(lockf)

进程通信-管道(lockf)

进程通信-管道(lockf)实验四进程通信一、实验目的以管道通信为例了解Linux系统中进程通信的基本原理。

二、预备知识1.系统调用lockf (fd,mode,size),对指定文件的指定区域(由size指示)进行加锁或解锁,以实现进程的同步与互斥。

其中fd是文件描述字;mode是锁定方式,=1表示加锁,=0表示解锁,size是指定文件fd的指定区域,用0表示从当前位置到文件尾。

2.进程管道的通信。

建立进程间的管道,格式为:pipe(fd); int fd[2]; 其中,fd[1] 是写端,向管道中写入; fd[0] 是读端,从管道中读出;本质上将其当作文件处理。

进程间可通过管道,用write与read来传递数据,但write 与read不可以同时进行,在管道中只能有4096字节的数据被缓冲。

写端fd[1] pipe(fd) 读端fd[0]write(fd[1],buf,size) read(fd[0],buf,size)3.write()写文件函数,把buf中的长度为size字符的消息送入管道入口fd[1]。

4.read()读文件函数,从管道出口fd[0]读出size字符的消息置入buf中。

5.系统调用sleep(second)用于进程的同步与互斥,自变量是暂停秒数。

其功能是使现行进程暂停执行由自变量规定的秒数。

6.sprintf()格式化输出到数组的函数。

7.系统调用exit()和wait()参考课本238页。

三、实验内容1.分析示例程序且编译执行。

编写一个程序,建立一个pipe,同时父进程产生一个子进程,子进程向pipe中写入一个字符串,父进程相隔5秒钟从该pipe中读出该字符串。

#include<stdio.h>main(){ int x, fd[2];char buf[30],s[30];pipe(fd);while((x=fork())==-1);if ( x==0){ sprintf(buf,”this is an example\n”);printf(“child procee running! \n”);write(fd[1],buf,30); /*把buf中的字符写入管道*/sleep(5); /*睡眠5秒,让父进程读*/exit(0); /*关闭x,子进程自我中止*/}else{ wait(0); /*父进程挂起直到其某一子进程中止为止*/read(fd[0],s,30);printf(“%s”,s);}2.编写一段程序,使用系统调用pipe()建立一条管道,同时父进程生成2个子进程分别向这条管道写一句话:child1 is sending a message! Child2 is sending a message! 父进程则循环从管道中读出信息,显示在屏幕上。

进程的管道通信实验

进程的管道通信实验

*******************实践教学*******************兰州理工大学计算机与通信学院2010年秋季学期操作系统原理课程设计题目:进程的管道通信实验专业班级:计算机(n)班姓名:桌面小箭头学号:0123456789指导教师:刘嘉成绩:目录前言 (3)摘要 (4)正文 (5)1.设计思想 (5)2.函数的关系调用图 (7)3.相关的各模块的伪码算法 (8)4.测试结果 (9)5.源程序(带注释) (10)总结 (13)参考文献 (14)致谢 (15)附件Ⅰ部分源程序代码 (16)前言通过该题目的设计过程,了解什么是管道,熟悉UNIX/LINUX支持的管道通信方式。

了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,练习并掌握UNIX提供的vi编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序。

编写程序实现进程的管道通信。

用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。

通过实践设计对操作系统的了解进一步加强,同时加深了对C语言以及vi编译器的熟悉和理解。

此外,将所学的课本理论知识再次运用到实践当中,做到理论与实践相结合,得到软件工程的综合训练,提高解决实际问题的能力。

摘要所谓管道,是指能够连接一个写进程和一个读进程的、同时允许它们以生产者-——消费者方式进行通信的一个共享文件,又称为pipe文件。

由写进程从管的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据关键词:父进程,读写进程,管道,通信,文件正文1.设计思想1.管道的创建:#include <unistd.h>int pipe(int fd[2])该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。

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

操作系统 进程的管道通信  实验报告
2、熟悉UNIX/LINUX支持的管道通信方式,并在程序中运用了pipe(),read()和write()等系统调用。
3、验证了lockf的加锁解锁作用,并验证了读写进程互斥。
4、进程中sleep(5)的作用是让所显示的内容休眠5秒钟,即等待5秒钟再显示。进程1和进程2也能对管道进行操作,因为他们同属于共同的管道,共同共享资源。
int j;
for(j=0;j<5;j++)
{
sprintf(OutPipe, "\n Child process %d is sending message!\n",j)eep(5);
}
lockf(fd[1], 0, 0);
exit(0);
进程的管道通信实验报告
学号
姓名
时间
2011年11月18日
专业
网络工程
班级
5班
实验题目:进程的管道通信实验
实验目的:
1、了解什么是管道
2、熟悉UNIX/LINUX支持的管道通信方式
3、通过进程多次的循环读写学习利用管道进行进程间的通信
4、验证lockf的加锁解锁作用
5、验证读写进程本身是否已经实现了互斥作用
}
else
{
printf("\nFather1\n");
int p;
for(p=0;p<5;p++)
{
read(fd[0], InPipe, 50);
printf("%s\n", InPipe);
}
printf("\nFather2\n");
int q;
for(q=0;q<5;q++)

进程之间的通信实验

进程之间的通信实验

实验:进程之间的通信管道1.Pipe函数与进程通信下面实验为使用管道进行父子进程间通信。

程序首先判断参数是否合法,因为输入的字符将从父进程通过发送到子进程中。

然后,调用pipe函数创建父子进程用于通信的管道。

使用fork函数创建子进程时,子进程会获得与父进程相同的资源,其中包括文件描述符信息。

因此,调用fork函数须在pipe函数调用前。

当父子进程通过管道进行通信时,files[1]为用于数据写入的文件描述符.因此,在子进程中,要读取管道中的数据可以调用read函数,而读取得文件描述符为files[0]。

对于父进程而言,写入数据需要调用write 函数,要写入的文件描述为files[1]。

#include <stdio.h>#include <unistd.h>int main(int argc,char* argv[]){int f_des[2];int pid;char msg[BUFSIZ];if(argc!=2){printf("Usage: %s message\n",argv[0]);return 1;}if(pipe(f_des)==-1){perror("cannot create the IPC pipe");return 1;}pid=fork();if(pid==-1){perror("cannot create new process");return 1;}else if(pid==0){close(f_des[1]);if(read(f_des[0],msg,BUFSIZ)==-1){perror("child process cannot read data from pipe");return 1;}elseprintf("in child process, receive message: %s\n",msg);_exit(0);}else {close(f_des[0]);if(write(f_des[1],argv[1],strlen(argv[1]))==-1){perror("parent process cannot write data to pipe");return 1;}elseprintf("in parent process, send message: %s\n",argv[1]);wait(NULL);_exit(0);}return 0;}2. Shell管道重订向的实现实现了在SHELL中的两个命令的组合。

用管道实现进程通信

用管道实现进程通信

操作系统实验报告用管道实现进程通信1. 实验目的(1)了解Windows系统环境下的进程通信机制。

(2)熟悉Windows系统提供的进程通信API。

2. 实验预备知识(1)根据《计算机操作系统实验指导》中相应内容填写(2)3. 实验内容一个基于有名管道的C/S模式应用,客户端发送命令到服务器,服务器执行命令,并将命令返回信息回传给客户端要求:A.客户端进程完成的工作1.建立私有有名管道2.打开服务端的共有有名管道3.等待用户输入命令4.将私有管道名和命令写入公有管道5.从私有管道中读服务端返回的结果B.服务端进程完成的工作1.建立服务端公有有名管道2.从公有有名管道中读取客户数据3.执行命令,并将结果写入客户私有管道4.实验代码服务器程序:// PipeClient.cpp : Defines the entrypoint for the console application.//#include "stdafx.h"#include "PipeClient.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {BOOL rc=0;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead;int nRetCode=0; int err=0;while(1){strcpy(InBuffer,"");strcpy(OutBuffer,"");printf("Input Data Please!\n");scanf("%s",InBuffer);rc=strcmp(InBuffer,"end");if(rc=0){rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer) ,OutBuffer,sizeof(OutBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_ WAIT);break;}rc=WaitNamedPipe(lpName,NMPWAIT_WAIT_FOREVER);if(rc==0){err=GetLastError();printf("Wait Pipe Fail!err=%d\n",err);exit(1);}else printf("Wait Pipe Success!\n");rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer) ,OutBuffer,sizeof(OutBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_W AIT);rc=strcmp(OutBuffer,"end");if(rc==0) break;if(rc==0){err=GetLastError();printf("Pipe Call Fail!err=%d\n",err);exit(1);}else printf("Pipe Call Success!\nData from Server is %s\n",OutBuffer);}printf("Now Client to be END\n");return nRetCode;}客户端程序:// 24.cpp : Defines the entry point for the console application.#include "stdafx.h"#include "PipeServer.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////// //////////////////////////// The one and only application objectCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {int nRetCode = 0;int err;BOOL rc;HANDLE hPipeHandle1;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead,BytesWrite;hPipeHandle1=CreateNamedPipe((LPCTSTR)lpName,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED|WRITE_DAC ,PIPE_TYPE_MESSAGE|PIPE_READMODE_BYTE|PIPE_WAIT, 1,20,30,NMPWAIT_USE_DEFAULT_WAIT,(LPSECURITY_ATTRIBUTES)NULL);if((hPipeHandle1==INVALID_HANDLE_VALUE)||(hPipeHand le1==NULL)){err=GetLastError();printf("Server Pipe Create Fail!err=%d\n");exit(1);}else printf("Server Pipe Create Success!\n");while(1){//guangdaorc=ConnectNamedPipe(hPipeHandle1,(LPOVERLAPPED)NU LL);if(rc==0){err=GetLastError();printf("Server Pipe Conner Fail err=%d\n",err);exit(2);}else printf("Server Pipe Conner Success!\n");strcpy(InBuffer,"");strcpy(OutBuffer,"");//命名管道读数据rc=ReadFile(hPipeHandle1,InBuffer,sizeof(InBuffer ),&BytesRead,(LPOVERLAPPED)NULL);if(rc==0&&BytesRead==0){err=GetLastError();printf("Server Read Pipe Fail!err=%d\n",err);exit(3);}else{printf("Server Read Pipe Success!\nDATA from Client is=%s\n",InBuffer);}rc=strcmp(InBuffer,"end");if(rc==0) break;printf("Please Input Data to Send\n");scanf("%s",OutBuffer);//向管道写数据rc=WriteFile(hPipeHandle1,OutBuffer,sizeof(OutBuf fer),&BytesWrite,(LPOVERLAPPED)NULL);if(rc==0) printf("Server Write Pipe Fail!\n");else printf("Server Write Pipe Success!\n");DisconnectNamedPipe(hPipeHandle1);rc=strcmp(OutBuffer,"end");if(rc==0) break;}printf("Now Server be END!\n");CloseHandle(hPipeHandle1);return nRetCode;}。

进程通信实验报告

进程通信实验报告

西安电子科技大学《操作系统原理》实验报告题目:进程通信实验报告班级: 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_)。

进程通信实验报告

进程通信实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

进程间通信实验资料

进程间通信实验资料

进程间通信(1)调试以下程序给出运行结果并分析其程序原理:#include <stdio.h>#include <unistd.h>#include <wait.h>#include <signal.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>(1)编写两个程实现进程的无名管道和有名管道通信。

要求分别调用pipe()、close()、write()、read()、popen()、pclose()、mknod()、mkfifo()、open()实现多个进程间的通信。

1.使用无名管道pipe(),进行父子进程之间的通信。

编写的程序如下:fork函数执行完毕后,返回值pid<0,则子进程创建失败,pid>0,则运行父进程,关闭读操作,进行写操作,将信息写进管道,写完后关闭写操作,父进程挂起。

Pid=0,运行子程序,关闭写操作,进行读操作,读完信息关闭读操作,子进程运行结束,父进程继续运行。

2.以命名行为参数的管道文件的示例。

(假设有一个可执行程序chcase,从标准输入设备读字符,将小写字母转化成大写字母并输出。

主程序使用popen创建管道,实现蒋某文本文件中的字幕转化成大写字母,其中的文本文件名作为参数传进来。

)命令行数量不为2时,输出结果如图所示;创建一个可执行程序chcase,此程序从标准输入设备读字符,将小写字母转化成大写字母并输出。

主程序使用popen()创建一个管道。

再创建一个文本文件,输入将要转换成大写字母的小写字母。

Popen创建的管道一头与文本文件相连,获取文本文件中的信息,将此信息通过管道传送给与管道另一端相连的可执行程序chcase,chcase获取文本文件中的小写字母后,将小写字母转换成大写字母输出。

基于管道的进程通信实验

基于管道的进程通信实验
实验内容:
编写一段程序,使用系统调用pipe()创建一无名管道,同时父进程创建一个子进程p1;并使子进程通过管道向父进程传递数据“p1 process is sending data to father.”,父进程通过管道接收到该字符串后输出。
实验要求:
(1)掌握系统调用pipe()的使用方法及其功能,理解管道通信原理;
系统调用将buf中的50个字节写入管道父进程返回父进程上cpu读出管道中的字符结果分析含实现中出错原因分析1为什么要在父进程与子进程之间通过管道同步传递数据
实现工具
C++
实现环境
Linux操作系统
实习内容(功能、目标)
实验目的:
创建无名管道,实现基于管道的进程间数据通信,掌握管道通信的方法及特征;并进一步理解互斥与同步的含义。
主要代码
注释
#include<iostream>
#include<wait.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
int main()
{
int r,p1,fd[2];
char buf[50],s[50];
pipe(fd);
cout<<"cannot read pipe"<<endl;
else
cout<<s<<endl;
}
}
//标准C++头文件
//创建无名管道
//创建子进程,如果等于-1,则创建失败,直到创建成功子进程P1;
//将字符数组“P1 process is sending data to father”复制到缓冲区buf[50]中;

进程和进程管道通信实验

进程和进程管道通信实验
close(pipe4[1]);
close(pipe4[0]);
close(pipe1[1]);
close(pipe3[0]);
pause();//暂停,等待进程3唤醒
//每次从管道1的0端读取x
//进行函数运算后,将函数运算结果fx通过管道1的1端写入
do{
read(pipe1[0],&x,sizeof(int));
CPU英特尔酷睿i7四核2.53GHz
主板LENOVO -英特尔HM65 (Cougar Point) [B3]
内存Ramaxel Technology 4G DDR3 SDRAM 1333 MHz双通道
显卡ATI Mobility Radeon HD 6500M
主硬盘希捷500GB
声卡High Definition Audio Controller [B3]
close(pipe2[1]);
close(pipe4[0]);
close(pipe1[1]);
close(pipe3[0]);
//子进程执行结束
printf("child%dread.\n",getpid());
exit(EXIT_SUCCESS);
}
}
}
//父进程执行结束
returnEXIT_SUCCESS;
网卡英特尔WiFi Link 1000 BGN
实验思路
本实验的设置首先要参考到实验一中的协同进程运行。首先创建3个子进程,分别处理f(x)、f(y)、f(x,y)。由于f(x)和f(x,y)、f(y)和f(x,y)之间需要交换数据,参考实验手册可以发现:管道是半双工的,所以需要4个管道。再加上管道默认的同步方式是同步读写,所以可以建立低些的循环,进行运算。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

试验9 进程间管道通信实验
学生姓名:李亚军学号:6100412196
专业班级:卓越计科121班
1.实验目的
通过编写有名管道多路通信实验,读者可进一步掌握管道的创建、读写等操作,同时,也复习使用select()函数实现管道的通信。

2.实验内容
(1)画出流程图。

该实验流程图如图8.9所示。

图8.9 8.6.1实验流程图
(2)编写代码。

该实验源代码如下所示。

/* pipe_select.c*/
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#define FIFO1 "in1"
#define FIFO2 "in2"
#define MAX_BUFFER_SIZE 1024 /* 缓冲区大小*/
#define IN_FILES 3 /* 多路复用输入文件数目*/
#define TIME_DELAY 60 /* 超时值秒数*/
#define MAX(a, b) ((a > b)?(a):(b))
int main(void)
{
int fds[IN_FILES];
char buf[MAX_BUFFER_SIZE];
int i, res, real_read, maxfd;
struct timeval tv;
fd_set inset,tmp_inset;
fds[0] = 0;
/* 创建两个有名管道*/
if (access(FIFO1, F_OK) == -1)
{
if ((mkfifo(FIFO1, 0666) < 0) && (errno != EEXIST))
{
printf("Cannot create fifo file\n");
exit(1);
}
}
if (access(FIFO2, F_OK) == -1)
{
if ((mkfifo(FIFO2, 0666) < 0) && (errno != EEXIST))
{
printf("Cannot create fifo file\n");
exit(1);
}
}
/* 以只读非阻塞方式打开两个管道文件*/
if((fds[1] = open (FIFO1, O_RDONL Y|O_NONBLOCK)) < 0) {
printf("Open in1 error\n");
return 1;
}
if((fds[2] = open (FIFO2, O_RDONL Y|O_NONBLOCK)) < 0) {
printf("Open in2 error\n");
return 1;
}
/*取出两个文件描述符中的较大者*/
maxfd = MAX(MAX(fds[0], fds[1]), fds[2]);
/*初始化读集合inset,并在读文件描述符集合中加入相应的描述集*/
FD_ZERO(&inset);
for (i = 0; i < IN_FILES; i++)
{
FD_SET(fds[i], &inset);
}
FD_SET(0, &inset);
_sec = TIME_DELAY;
_usec = 0;
/*循环测试该文件描述符是否准备就绪,并调用select()函数对相关文件描述符做相应操作*/
while(FD_ISSET(fds[0],&inset)
|| FD_ISSET(fds[1],&inset) || FD_ISSET(fds[2], &inset))
{
/* 文件描述符集合的备份,免得每次进行初始化*/
tmp_inset = inset;
res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv);
switch(res)
{
case -1:
{
printf("Select error\n");
return 1;
}
break;
case 0: /* Timeout */
{
printf("Time out\n");
return 1;
}
break;
default:
{
for (i = 0; i < IN_FILES; i++)
{
if (FD_ISSET(fds[i], &tmp_inset))
{
memset(buf, 0, MAX_BUFFER_SIZE);
real_read = read(fds[i], buf, MAX_BUFFER_SIZE);
if (real_read < 0)
{
if (errno != EAGAIN)
{
return 1;
}
}
else if (!real_read)
{
close(fds[i]);
FD_CLR(fds[i], &inset);
}
else
{
if (i == 0)
{/* 主程序终端控制*/
if ((buf[0] == 'q') || (buf[0] == 'Q'))
{
return 1;
}
}
else
{/* 显示管道输入字符串*/
buf[real_read] = '\0';
printf("%s", buf);
}
}
} /* end of if */
} /* end of for */
}
break;
} /* end of switch */
} /*end of while */
return 0;
}
(3)编译并运行该程序。

(4)另外打开两个虚拟终端,分别键入“cat > in1”和“cat > in2”,接着在该管道中键入相关内容,并观察实验结果。

主程序截图
In1管道截图
In2截图
3.根据实验结果完成试验报告
(1)在第一个虚拟终端上运行主程序:
$ ./pipe_select(必须先运行主程序)
SELECT CALL
select call
TEST PROGRAMME
test programme
END
end
q /* 在终端上输入’q’或’Q’立刻结束程序运行*/
(2)在第二个终端上运行cat>in1后输入字符串,将在第一个终端上看到同步输入情况$ cat > in1
SELECT CALL
TEST PROGRAMME
END
(3)在第三个终端上运行cat>in1后输入字符串,将在第一个终端上看到同步输入情况
$ cat > in2
select call
test programme
end
实验总结:
这个实验总的来说还是比较简单,部分函数需要参考串口编程的内容,实验原理就像前面一个实验利用一般文件模拟管道文件一样,只不过现在换成了真正的管道文件,需要注意的是这个实验在运行cat命令时需要将目录cd到当前程序目录,否则看不到实验结果。

相关文档
最新文档