实验题目:进程管理及进程通信

合集下载

操作系统实验报告进程管理

操作系统实验报告进程管理

操作系统实验报告进程管理操作系统实验报告:进程管理引言操作系统是计算机系统中的核心软件,负责管理计算机的硬件资源和提供用户与计算机之间的接口。

进程管理是操作系统的重要功能之一,它负责对计算机中运行的各个进程进行管理和调度,以保证系统的高效运行。

本实验报告将介绍进程管理的基本概念、原理和实验结果。

一、进程管理的基本概念1. 进程与线程进程是计算机中正在运行的程序的实例,它拥有独立的内存空间和执行环境。

线程是进程中的一个执行单元,多个线程可以共享同一个进程的资源。

进程和线程是操作系统中最基本的执行单位。

2. 进程状态进程在运行过程中会经历不同的状态,常见的进程状态包括就绪、运行和阻塞。

就绪状态表示进程已经准备好执行,但还没有得到处理器的分配;运行状态表示进程正在执行;阻塞状态表示进程由于某些原因无法继续执行,需要等待某些事件的发生。

3. 进程调度进程调度是操作系统中的一个重要任务,它决定了哪个进程应该获得处理器的使用权。

常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)和时间片轮转等。

二、进程管理的原理1. 进程控制块(PCB)PCB是操作系统中用于管理进程的数据结构,它包含了进程的各种属性和状态信息,如进程标识符、程序计数器、寄存器值等。

通过PCB,操作系统可以对进程进行管理和控制。

2. 进程创建与撤销进程的创建是指操作系统根据用户的请求创建一个新的进程。

进程的撤销是指操作系统根据某种条件或用户的请求终止一个正在运行的进程。

进程的创建和撤销是操作系统中的基本操作之一。

3. 进程同步与通信多个进程之间可能需要进行同步和通信,以实现数据共享和协作。

常见的进程同步与通信机制包括互斥锁、信号量和管道等。

三、实验结果与分析在本次实验中,我们使用了一个简单的进程管理模拟程序,模拟了进程的创建、撤销和调度过程。

通过该程序,我们可以观察到不同调度算法对系统性能的影响。

实验结果显示,先来先服务(FCFS)调度算法在一些情况下可能导致长作业等待时间过长,影响系统的响应速度。

操作系统原理-进程管理与进程通信

操作系统原理-进程管理与进程通信

广州大学学生实验报告一、实验目的1、掌握进程的概念,明确进程的含义2、认识并了解并发执行的实质3、了解什么是管道4、熟悉UNIX/LINUX支持的管道通信方式二、实验器材1、计算机一台。

2、Linux三、实验内容1、编写一段程序,使用系统调用fork( )创建两个子进程。

当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。

试观察记录屏幕上的显示结果,并分析原因。

2、修改上述程序,每一个进程循环显示一句话。

子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。

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

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

四、实验步骤、记录和结果实验二进程管理实验(一)进程的创建实验1.使用vi输入下面代码编译运行结果:从执行情况来看,可能输出bac,bca...2.使用vi输入下面代码编译运行结果:分析原因:1、从进程并发执行来看,各种情况都有可能。

上面的三个进程没有同步措施,所以父进程与子进程的输出内容会叠加在一起。

输出次序带有随机性。

2、由于函数printf( )在输出字符串时不会被中断,因此,字符串内部字符顺序输出不变。

但由于进程并发执行的调度顺序和父子进程抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。

这与打印单字符的结果相同。

实验总结:通过这次实验,即时在多进程中printf()在输出字符串时不会被中断。

电大操作系统实验报告3_ 进程管理实验

电大操作系统实验报告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 程序,创建一个子进程,子进程进入睡眠状态一段时间,然后被唤醒并输出状态转换信息。

实验报告三进程管理及进程通信

实验报告三进程管理及进程通信

实验三进程管理及进程通信实验环境:Linux操作系统实验目的:(1)利用Linux提供的系统调用设计程序,加深对进程概念的理解。

(2)体会系统进程调度的方法和效果。

(3)了解进程之间的通信方式以及各种通信方式的使用。

实验方法:用vi 编写c 程序(假定程序文件名为prog1.c)编译程序$ gcc -o prog1.o prog1.c或 $ cc -o prog1.o prog1.c运行$./prog1.o实验内容及步骤:实验1编写程序。

显示进程的有关标识(进程标识、组标识、用户标识等)。

经过5 秒钟后,执行另一个程序,最后按用户指示(如:Y/N)结束操作。

编程截图:运行结果:实验2参考例程1,编写程序。

实现父进程创建一个子进程。

体会子进程与父进程分别获得不同返回值,进而执行不同的程序段的方法。

例程1:利用fork()创建子进程/* 用fork()系统调用创建子进程的例子*/main(){int i;if (fork()) /*父进程执行的程序段*/i=wait(); /* 等待子进程结束*/{printf("It is parent process.\n");printf("The child process,ID number %d, is finished.\n",i);}else{Printf(“It is child process.\n”);Sleep(10);Exit();}}运行结果:思考:子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的?答:是由父进程用fock()函数创建形成的,通过exit()函数自我结束,子进程被创建后核心将其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程所有文件。

实验3参考例程2,编写程序。

父进程通过循环语句创建若干子进程。

探讨进程的家族树以及子进程继承父进程的资源的关系。

操作系统实验报告进程通信管理资料

操作系统实验报告进程通信管理资料

漳州师范学院
实验报告
班级 13网络1班学号1308990337 姓名成绩
理解分析:1.先创建父进程,由父进程分别产生子进程1和子进程
p2,parent。

2.给父进程中断信号,父进程开始终止子进程,signal(SIGINT, SIG_IGN);语句,相当于使子进程忽略键入信号,不会将子进程终止,程序可以正常运行。

于是输出child process by parent!和child process 2 is killed by parent!
理解分析:在该管道通信中,有时是子进程p1,p2往管道中传送数据完后父进程再从管道中读取数据,有时是子进程p1往管道中传送数据后父进程从管道中读取数据,然后子进程p2再往管道中传送数据,父进程再从管道中读取数据。

1)管道通信的概念是什么
管道通信即发送进程以字符流形式将大量数据送入管道,接收进程可从管道接收数据,二者利用管道进行通信。

2)同步和互斥的概念是什么,在程序中如何实现的
注:如果填写内容超出表格,自行添加附页。

进程通信的实验报告

进程通信的实验报告

一、实验目的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操作,实现进程间的同步和互斥。

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

操作系统实验_实验1课案

操作系统实验_实验1课案

广州大学学生实验报告开课学院及实验室:计算机科学与工程实验室 2015年11月11日实验课操作系统成绩程名称实验项进程管理与进程通信指导老师陈康民目名称(***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***)进程管理(一)进程的创建实验一、实验目的1、掌握进程的概念,明确进程的含义2、认识并了解并发执行的实质二、实验内容1、编写一段程序,使用系统调用fork( )创建两个子进程。

当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。

试观察记录屏幕上的显示结果,并分析原因。

2、修改上述程序,每一个进程循环显示一句话。

子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。

三、实验步骤1、编写一段程序,使用系统调用fork( )创建两个子进程。

代码:#include <stdio.h>main( ){int p1,p2;while((p1=fork( ))= = -1); /*创建子进程p1*/if (p1= =0) putchar('b');else{while((p2=fork( ))= = -1); /*创建子进程p2*/if(p2= =0) putchar('c');else putchar('a');}}运行结果:bca,bac, abc ,……都有可能。

2、修改上述程序,每一个进程循环显示一句话。

子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。

代码:#include <stdio.h>main( ){int p1,p2,i;while((p1=fork( ))= = -1); /*创建子进程p1*/if (p1= =0)for(i=0;i<10;i++)printf("daughter %d\n",i);else{while((p2=fork( ))= = -1); /*创建子进程p2*/if(p2= =0)for(i=0;i<10;i++)printf("son %d\n",i);elsefor(i=0;i<10;i++)printf("parent %d\n",i);}}结果:parent…son…daughter..daughter..或parent…son…parent…daughter…等四、分析原因除strace 外,也可用ltrace -f -i -S ./executable-file-name查看以上程序执行过程。

电大操作系统实验2:进程管理实验

电大操作系统实验2:进程管理实验

电大操作系统实验2:进程管理实验
实验目的:
1.加深对进程概念的理解,特别是进程的动态性和并发性。

2.了解进程的创建和终止。

3.学会查看进程的状态信息。

4.学会使用进程管理命令。

实验要求:
1.理解有关进程的概念,能够使用ps命令列出系统中进
程的有关信息并进行分析。

2.理解进程的创建和族系关系。

3.能够使用&,jobs,bg,at等命令控制进程的运行。

实验内容:
1.使用ps命令查看系统中运行进程的信息。

实验环境:
实验步骤和结果:
1.输入ps命令,可以报告系统当前的进程状态。

2.输入ps-e命令,可以显示系统中运行的所有进程,包括系统进程和用户进程。

3.输入ps-f命令,可以得到进程的详细信息。

进程控制:
1.后台进程
1) $grep "注册用户名" /etc/passwd。

/tmp/abc &
2.作业控制
1) 进程休眠60秒Sleep 60 &
2) 进程休眠30秒Sleep 30 &
3) 查看进程状态Jobs
4) 将睡眠30秒的sleep命令放在前台执行fg%2
3.发送中断信号
1) 后台运行sleep命令$sleep 120 &
2) 查看sleep进程的状态$ps-p pid
3) 终止sleep命令$kill -9 pid。

进程通信实验报告

进程通信实验报告

操作系统实验报告(三)进程通信专业:软件工程姓名: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;}}}}。

操作系统原理第一次实验

操作系统原理第一次实验
图二
内容三:敲通如下程序,写出运行结果,分析程序功能。
#include <stdio.h>
#include <pthread.h>
void *ptest(void *arg)
{
printf(" This is the new thread!" );
return(NULL);
}
main()
3
{
pthread_t tid;
实验一进程管理、管道通信
一.实验名称:
进程管理、管道通信
二.实验目的:
1、熟悉linux下利用gcc、gdb编译、调试C程序
2、掌握进程的概念,明确进程的含义
3、认识并了解并发执行的实质
4、掌握进程间无名管道的通信
三.实验准备:
1、预习linux下利用gcc编译c程序。
2、参考课件及资料掌握进程的创建过程。
thread!”返回值为空,程序休眠后结束程序。
图三
内容四:敲通管道通信(课件)例题,写出运行结果,分析程序功能
#include<stdlib.h>
#include<stdio.h>
voidmain()
{
int x,fd[2];
char buf[30],s[30]; pipe(fd); while((x=fork())==-1); if(x==0)
3、参考课件及资料掌握进程的并发执行。
4、参考课件及资料掌握进程间无名管道的通信。
四.实验内Байду номын сангаас:
内容一:敲通如下程序,分析运行结果。
#include <stdio.h>
main()

进程管理实验报告

进程管理实验报告

一、实验目的1. 理解进程的概念及其在操作系统中的作用。

2. 掌握Linux环境下进程的创建、调度、同步与通信等基本操作。

3. 通过实验加深对进程管理知识的理解和应用。

二、实验环境1. 操作系统:Linux2. 实验工具:xshell、vi编辑器、gcc编译器三、实验内容1. 进程的创建与终止2. 进程的调度策略3. 进程同步与互斥4. 进程间的通信四、实验步骤1. 进程的创建与终止(1)编写C语言程序,使用fork()系统调用创建子进程。

(2)通过exec()系统调用执行新的程序,实现进程替换。

(3)使用waitpid()函数等待子进程结束。

(4)使用kill()函数终止指定进程。

2. 进程的调度策略(1)观察Linux系统中进程调度算法,如FCFS、RR、SJF等。

(2)编写程序,模拟不同的调度算法,分析其性能。

3. 进程同步与互斥(1)使用信号量实现进程同步,如生产者-消费者问题。

(2)使用互斥锁实现进程互斥,如银行家算法。

4. 进程间的通信(1)使用管道实现进程间通信。

(2)使用消息队列实现进程间通信。

(3)使用共享内存实现进程间通信。

五、实验结果与分析1. 进程的创建与终止通过实验,我们掌握了使用fork()、exec()、waitpid()、kill()等系统调用创建、替换、等待和终止进程的方法。

在实际应用中,进程的创建与终止是进程管理的基础。

2. 进程的调度策略通过模拟不同的调度算法,我们发现FCFS算法简单,但效率较低;RR算法适用于交互式系统,但可能导致进程饥饿;SJF算法效率较高,但难以实现。

在实际应用中,应根据系统需求选择合适的调度算法。

3. 进程同步与互斥通过使用信号量和互斥锁,我们实现了进程同步与互斥。

在实际应用中,进程同步与互斥是保证系统正确性和效率的关键。

4. 进程间的通信通过使用管道、消息队列和共享内存,我们实现了进程间的通信。

在实际应用中,进程间的通信是提高系统并发性和效率的重要手段。

实验二进程和进程通信

实验二进程和进程通信

实验二进程和进程通信实验二进程和进程通信一、实验目的1、通过使用进程和进程通信方面的系统调用的,加深理解有关进程方面的基本概念。

通过实验对进程有进一步的感性认识,掌握系统V的IPC机制。

二、实验内容1、设计一个程序,创建一个子进程,使父子进程合作,协调地完成某一功能。

要求在该程序中还要使用进程的睡眠、进程图象改换、父进程等待子进程终止、信号的设置与传送(包括信号处理程序)、子进程的终止等有关进程的系统调用。

2、分别利用UNIX的消息通信机制、共享内存机制(用信号灯实施进程间的同步和互斥)实现两个进程间的数据通信。

具体的通信数据可从一个文件读出,接收方进程可将收到的数据写入一个新文件,以便能判断数据传送的正确性(对文件操不熟悉的同学可不必通过读写文件,只要键盘输入和输出至屏幕进行比较即可)。

3、编写一个程序,生成若干个线程,通过这些并发线程的合作,完成较复杂的任务。

通过测试程序的运行结果,比较进程和进程、线程和线程之间对外部变量、静态变量和动态变量的共享方式的相同和不同之处。

三、实验代码3.1 父子进程通信#include#includemain(){int pid,status = 1;void func();signal(SIGUSR1,func); /* 预置信号处理程序,将SIGUSR1设置为func函数的功能*/while ((pid=fork( ))==-1);if (pid) { /* 父进程*/printf("It is the parent process.\n");printf("Parent: will send signal.\n");kill(pid,SIGUSR1); /* 发送信号,即发送执行func函数的信息*/ pid = wait(&status); /* 父进程等待子进程终止*/printf("Child process %d,status=%d \n",pid,status);}else { /* 子进程*/sleep (2); /* 等待接受信号*/printf("It is the child process.\n");printf("Child:signal is received.\n");execvp ("pwd",(char*)0); /* 映像改换,显示当前工作区,exevcp不用给出具体路径,(char*)0指向pwd命令*/printf("execl error.\n"); /* 映像改换失败*/exit(2);}printf ("Parent process finish. \n");}void func (){system("date");}3.2 消息通信/* msgcom.h */#include#include#include#include#define MSGKEY 5678struct msgtype{long mtype;int text;};#include "msgcom.h"main(){ /* 请求进程*/struct msgtype buf;int qid,pid;qid=msgget(MSGKEY,IPC_CREAT|0666); /* MSGKEY为约定的消息队列关键字,访问控制权限为0666 */buf.mtype=1; /* 请求进程发送消息标识为1 */buf.text=pid=getpid(); /* 请求进程发送消息内容为进程标识*/ msgsnd(qid,&buf,sizeof(buf.text), IPC_NOWAIT|04000); /* 发送消息正文长度为buf的大小*/msgrcv(qid,&buf,512,pid,MSG_NOERROR); /* 指定接收mtype=pid的信息,即请求进程发送给服务器处理后的信息*/ printf("Request received a massags from server, type is: %d\n",buf.mtype);}#include "msgcom.h"main(){ /* 服务器进程*/struct msgtype buf;int qid;if((qid=msgget(MSGKEY,IPC_CREAT|0666))== -1)return(-1); /* 出错处理*/while(1){msgrcv(qid,&buf,512,1,MSG_NOERROR); /* 接收所有请求进程发送的消息*/printf("Server receive a request from process %d\n",buf.text);buf.mtype=buf.text; /* 将请求进程的标识数作为mtype的值,以便于请求进程识别*/msgsnd(qid,&buf,sizeof(int),IPC_NOW AIT|04000); /* 将消息发送给请求进程*/ }}3.3 共享内存#include#include#include#include#include#define SHMKEY 18001 /* 共享内存关键字*/#define SHMKEY2 18002#define SIZE 1024 /* 共享内存长度*/#define SEMKEY1 19001 /* 信号灯组1关键字*/#define SEMKEY2 19002 /* 信号灯组2关键字*/#define SEMKEY3 19003 /* 信号灯组3关键字*/static void semcall(sid,op)int sid,op;{struct sembuf sb;sb.sem_num = 0; /* 信号灯编号0 */sb.sem_op = op; /* 信号灯操作数加1或减1 */sb.sem_flg = 0; /* 操作标志*/if(semop(sid,&sb,1) == -1)perror("semop"); /* 出错处理*/};int creatsem(key) /* 信号灯组创建及初始化程序*/key_t key;{int sid;union semun { /* 如sem.h中已定义,则省略*/int val;struct semid_ds *buf;ushort *array;} arg;if((sid=semget(key,1,0666|IPC_CREAT))==-1) /* 创建1个关键字为1的信号灯组,访问控制权限为0666 */perror("semget"); /* 出错处理*/arg.val=1; /* 初值为1 */if(semctl(sid,0,SETV AL,arg)==-1) /* 将信号灯组的第一个信号灯的初值置1 */perror("semctl"); /* 出错处理*/return(sid);}void P(sid)int sid;{semcall(sid,-1); /*对关键字为sid信号灯组值减1,相当于wait */}void V(sid)int sid;{semcall(sid,1); /*对关键字为sid信号灯组值加1,相当于signal */}main(){char *segaddr,*segaddr2;int segid,segid2,sid1,sid2,sid3;if((segid=shmget(SHMKEY,SIZE,IPC_CREAT|0666))==-1) /* 创建共享内存段*/perror("shmget"); /* 出错处理*/if((segid2=shmget(SHMKEY2,SIZE,IPC_CREA T|0666))==-1) /* 创建共享内存段2 */perror("shmget"); /* 出错处理*/segaddr=shmat(segid,0,0); /* 将共享内存映射到进程数据空间*/segaddr2=shmat(segid2,0,0); /* 将共享内存2映射到进程数据空间*/sid1=creatsem(SEMKEY1); /* 创建三个信号灯,初值为1 */sid2=creatsem(SEMKEY2);sid3=creatsem(SEMKEY3);P(sid2); /* 置信号灯2值为0,表示缓冲区1空*/P(sid3); /* 置信号灯3值为0,表示缓冲区2空*/if(!fork()){if(!fork()){while(1){ /* 子进程的子进程,接收和输出*/P(sid3);printf("Received from Parent: %s\n",segaddr2);printf("Received from Grandparent: %s\n",segaddr);V(sid1);}}while(1){ /* 子进程,输入和存储*/P(sid2);scanf("%s",segaddr2);V(sid3);}}while(1) { /* 父进程,输入和存储*/P(sid1);scanf("%s",segaddr);V(sid2);}}3.4 线程#include#include#includeint nthreads = 1; /* 线程执行函数,传入参数为线程序号,传出参数为项: (序号+1) */ void *dowork (void *params){int j = *(int *)params;int term = j+1;*(int *)params = term;printf ("the thread [%d]: term =%d\n",j,term);}void main(int argc,char **argv){int i;pthread_t threads[100];int pthread_data[100];float mean = 0; /* 平均数*/float variance = 0; /* 方差*/if(argc==2)nthreads = atoi (argv[1]); /* 将命令行字符串参数转换为整数*/for (i=0; i<="">pthread_data [i] = i ;pthread_create (&threads[i], NULL, dowork, &pthread_data[i]); /* 创建线程*/ }for (i=0; i<="">pthread_join (threads [i], NULL); /* 等待子线程结束,汇合结果*/mean += (float)pthread_data[i];}mean = mean / nthreads;for(i=0; i<="">variance += (float)(pthread_data[i]-mean)*(pthread_data[i]-mean);}variance = variance / nthreads;printf("The total threads is %d\n",nthreads);printf("The mean = %f\n", mean);printf("The variance = %f\n",variance);}四、运行结果3.1 父子进程通信父进程向子进程发送的消息为函数system(“date”)即显示日期时间。

进程通信实验报告

进程通信实验报告

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

进程通信实验报告

进程通信实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

实验四 进程通信实验

实验四 进程通信实验

实验四:进程通信实验实验学时:3学时一、实验目的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都是消息类型。

实验四进程通信

实验四进程通信

实验四 进程间通信一、实验目的1. 掌握利用管道机制实现进程间的通信的方法2. 掌握利用消息缓冲队列机制实现进程间的通信的方法3. 掌握利用共享存储区机制实现进程间的通信的方法4. 了解Linux系统中进程软中断通信的基本原理二、实验学时2学时三、实验内容1.掌握实现进程间通信的系统调用的功能和方法进程通信,是指进程之间交换信息。

从这个意义上讲,进程之间的同步、互斥也是一种信息交换,也是一种通信。

但是,这里所说的“通信”是指进程之间交换较多的信息这样一种情况,特别是在由数据相关和有合作关系的进程之间,这种信息交换是十分必要和数量较大的。

进程间通信是协调解决多个进程之间的约束关系,实现进程共同进展的关键技术,是多道系统中控制进程并发执行必不可少的机制。

(1)进程的通信方式:a. 直接通信是指信息直接传递给接收方,如管道。

在发送时,指定接收方的地址或标识,。

在接收时,允许接收来自任也可以指定多个接收方或广播式地址, send(Receiver, message)。

意发送方的消息,并在读出消息的同时获取发送方的地址, receive(Sender,message)b. 间接通信:借助于收发双方进程之外的共享数据结构作为通信中转,如消息队列。

这种数据结构称为缓冲区或信箱。

通常收方和发方的数目可以是任意的。

(2)进程间通信的类型:a. 共享存储器系统:基于共享数据结构的通信方式:只能传递状态和整数值(控制信息),包括进程互斥和同步所采用的信号量机制。

速度快,但传送信息量小,编程复杂,属于低级通信;基于共享存储区的通信方式:能够传送任意数量的数据,属于高级通信。

b. 消息传递系统:在消息传递系统中,进程间的数据交换以消息为单位,用户直接利用系统提供的一组通信命令(原语)来实现通信。

c. 管道通信:管道是一条在进程间以字节流方式传送的通信通道。

它由OS 核心的缓冲区(通 常几十KB)来实现,是单向的;在实质上,是一个有OS 维护的特殊共享文件,常用于命令行所指定的输入输出重定向和管道命令。

实验一 进程通信——管道和信号实验报告

实验一 进程通信——管道和信号实验报告

进程管理实验报告【姓名】…【学号】…【实验题目】进程管理【实验目的】a.加深对进程概念的理解,明确进程和程序的区别;b.进一步认识并发执行的实质;c.分析进程争用资源的现象,学习解决进程互斥的方法;d.了解Unix系统中进程通信的基本原理【实验预备知识】学习UNIX中有关进程创建、控制和通信的部分。

【实验方法】利用Unix系统提供的内部函数创建进程并管理进程,从而实现进程控制、进程间通信和进程的管道通信。

【实验内容】(1)进程的创建编写程序,创建两个子进程。

当此程序运行时,系统中有一个父进程和两个子进程。

父进程在屏幕上显示“Parent”,子进程分别在屏幕上显示“Child1”和“Child2”。

(2)进程控制如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。

(3)进程间通信①编制一个程序,使其实现进程的软中断通信。

要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即DEL键);当捕捉到中断信号后,父进程用系统调用kill()向两个进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child Process 1 is Killed by Parent!Child Process 2 is Killed by Parent!父进程等待两个子进程终止后,输出如下信息后终止:Parent Process is killed!②在上面的程序中增加语句signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN),观察执行结果,并分析原因。

(4)进程的管道通信编制一段程序,实现进程的通信。

使用系统调用pipe()建立一条管道;两个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!而父进程则从管道中读出来自两个子进程的信息,显示在屏幕上。

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

实验题目:进程管理及进程通信姓名________ 学号________ 实验日期2016/10/12 __________ 实验环境:VMware Workstation 中的Ubuntu 64 位操作系统。

实验目的:利用Linux提供的系统调用设计程序,加深对进程概念的理解。

体会系统进程调度的方法和效果。

了解进程之间的通信方式以及各种通信方式的使用。

实验内容:用vi编写使用系统调用的C语言程序。

操作过程及结果:实验1:编写程序。

显示进程的有关标识(进程标识、组标识、用户标识等)。

经过5秒钟后,执行另一个程序,最后按用户指示(如:Y/N)结束操作。

结果:实验2:编写程序。

实现父进程创建一个子进程。

体会子进程与父进程分别获得不同返回值,进而执行不同的程序段的方法。

结果:思考:子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的?答:是由父进程用fork()函数创建形成的,通过exit()函数自我结束,子进程被创建后核心将其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程所有文件。

实验3:编写程序。

父进程通过循环语句创建若干子进程。

探讨进程的家族树以及子进程继承父进程的资源的关系。

结果:wyk^ubuntu :gee projl-o proj1 wykQubuntu./proJiMy ptd is 2790, my father pid i.s Z687 0 ptd=2791 pptd=279Q1ptd=2792 pptd=27912ptd=2793 pptd=27922792iThe chile 2793 is firtsh^d.2791;The chile 27S2 Is 2 ptd=2794 pptd=2791 2791:The chile 2794 is 2799:The chile 2791 is1ptd=279S pptd=279&2ptd=2796 ppid=2795 2795;The chile 2756 is 2799:The chile 2795 Is 2ptd^2797 pptd^279Q 2799:The chile 2797 isfinished.firitshed.finished *finished 4finished,finished +思考:① 画出进程的家族树。

子进程的运行环境是怎样建立的?反复运行此程序看会有什么情况?解释一下。

② 修改程序,使运行结果呈单分支结构,即每个父进程只产生一个子进程。

画出进程树,解释该程序。

答1:反复运行,子进程的编号在不断变化,但是初始的父进程的编号不会变,因为:父进程始终 是该程序在虚拟机操作系统下的进程号, 但是子进程是该父进程创建的子进程不断增加而得的,子进程的编号应该是顺序递增的。

答2:#i nclude <stdio.h> #in elude <sys/types.h>#in elude <uni std.h>main () {int i, pid; for (i=1; i<4; i++)if (pid=fork()) break; }实验4:编写程序。

使用fork()和exec()等系统调用创建三个子进程。

子进程分别启动不同程序,并结束。

反复执行该程序,观察运行结果,结束的先后,看是否有不同次序。

结果:Parent process is waiting for chile process return ! Wed Oct 5 19:13:58 PDT 2016child process 2 terminated with child process 1child process 1 terminated with Desktop Downloads PicturesDocuments Music progl.c childprocess 3 terminated with Allchild processes terminated ・ Parent process terminated .思考:子进程运行其它程序后, 进程运行环境怎样变化的?反复运行此程序看会有什么情况? 解释一下。

status 0 status 0 proglTemplates Public Videos status 0程标识号不改变,除此之外的旧进程的其他信息,代码段,数据段,栈段等均被新程序的信息所代替。

新程序从自己的main()函数开始进行。

反复运行此程序发现结束的先后次序是不可预知的,每次运行结果不一样。

原因是当每个子进程运行其他程序时,他们的结束随着其他程序的结束而结束,所以结束的先后次序在改变。

实验5:编写程序。

验证子进程继承父进程的程序、数据等资源。

如用父、子进程修改公共变量和私有变量的处理结果;父、子进程的程序区和数据区的位置。

结果:思考:子进程被创建后,对父进程的运行环境有影响吗?解释一下。

答:子进程被创建后,对父进程的运行环境无影响,因为当子进程在运行时,他有自己的代码段和数据段,这些都可以作修改,但是父进程的代码段和数据段是不会随着子进程数据段和代码段的改变而改变。

实验6:复习管道通信概念,编写一个程序。

父进程创建两个子进程,父子进程之间利用管道进行通信。

要求能显示父进程、子进程各自的信息,体现通信效果。

结果:思考:①什么是管道?进程如何利用它进行通信的?解释一下实现方法。

②修改睡眠时机、睡眠长度,看看会有什么变化。

请解释。

③加锁、解锁起什么作用?不用它行吗?答1管道:是指能够连接一个写进程和一个读进程、并允许它们以生产者-消费者方式进行通信的一个共享文件,又称为pipe文件。

由于写进程从管道的入端将数据写入管道,而读进程则从管道的出端读出数据。

进程利用管道进行通信:将索引结点中的直接地址项作为一个循环队列来管理,为它设置一个读指针,一个写指针,按先进先出的顺序读写。

在该例中,利用fd[2]这个数组来确定读写替换。

执行进程1时,lockf(fd[1],1,0) 使得管道写入端加锁,这样就可以进行写入了,write(fd[1],buf,50); /* 信息写入管道*/lockf(fd[1],0,0); /*管道写入端解锁*/这样其他进程就能继续进行读写操作了。

然后执行进程2的写入,过程同上。

最后父进程的进行读,read(fd[0],s,50) 。

读写之间、写和写之间也是互斥的,多以会加锁。

答2:修改1号子进程的睡眠时间长度修改为20s后,等待了较长时间,然后出现了下面的结果:2号子进程先执行了,然后父进程执行。

原因应该是:父进程进行wait()等待子进程,由于2号子进程的睡眠时间短,于是就先执行完了2号子进程的内容,然后才第二次wait()时才执行1号子进程,最后父进程结尾。

答3:加锁解锁的作用:为了使得读、写进程能够互斥的访问pipe文件,每逢继承访问pipe 文件前,都需检查该索引节点是否已经上锁,若已经锁住,进程便睡眠等待;否则,将索引节点上锁,然后再进行读、写操作,操作结束后又将该索引节点解锁,并唤醒因该节点上锁而睡眠的进程。

这样就能实现了读、写之间的互斥操作,每次只能有一个进程进行访问pipe文件。

实验7:编程验证:实现父子进程通过管道进行通信。

进一步编程,验证子进程结束,由父进程执行撤消进程的操作。

测试父进程先于子进程结束时,系统如何处理“孤儿进程”的。

只要在父进程后加上wait()函数,然后打印“子进程已经结束”,一旦子进程结束,父进程撤销进程。

当父进程先于子进程终止时•所有子进程的父进程改变为in it进程称为进程由init进程领养。

实验8:编写两个程序,一个是服务者程序,一个是客户程序。

执行两个进程之间通过消息机制通信。

消息标识MSGKEY可用常量定义,以便双方都可以利用。

客户将自己的进程标识 (pid) 通过消息机制发送给服务者进程。

服务者进程收到消息后,将自己的进程号和父进程号发送给客户,然后返回。

客户收到后显示服务者的pid和ppid,结束。

结果:思考:想一下服务者程序和客户程序的通信还有什么方法可以实现?解释一下你的设想, 兴趣试一试吗。

答:还可以通过管道操作。

或者用信号量机制来实现。

信号量是一个整形计数器,用来控制多个进程对共享资源的访问。

或者通过消息队列信号机制,通过向消息队列发送信息、接收信息来实现进程间的通信。

实验9:编程实现软中断信号通信。

父进程设定软中断信号处理程序,向子进程发软中断信号。

子进程收到信号后执行相应处理程序。

结果:思考:这就是软中断信号处理,有点儿明白了吧?讨论一下它与硬中断有什么区别?看来还挺管用,好好利用它。

答:软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的。

软中断是由程序调用发生的,而硬中断是由外设引发的。

实验10:用信号量机制编写一个解决生产者一消费者问题的程序。

研究并讨论:1.讨论Linux系统进程运行的机制和特点,系统通过什么来管理进程?系统通过进程控制块(PCB来管理进程。

PCE主要分为四部分:(1)进程表项,(2)U区, (3)系统区表,(4)进程区表。

2.C语言中是如何使用Linux提供的功能的?用程序及运行结果举例说明。

Lin ux系统的一种用户接口是程序员用的编程接口,即系统调用。

系统调用的目的是使用户可以使用操作系统提供的有关进程控制、文件系统、输入输出系统、设备管理、通信及存储管理等方面的功能,而不必涉及系统内部结构和硬件细节,大大减少用户程序设计和编程难度。

Lin ux的系统调用以标准实用子程序形式提供给用户在编程中使用。

一般使用系统调用应注意以下三点:(1)函数所在的头文件(2)函数调用格式,包括参数格式、类型。

(3)返回值格式、类型。

例如:程序:在该程序中调用了系统程序"date".#in elude <uni std.h>main (){execlp("date","date",(char *)0);return;}结果如下:3.什么是进程?如何产生的?举例说明。

答:进程实体是程序段、相关的数据段和PCB三部分构成的实体。

进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

进程的产生:进程是由创建而产生的,即使进程实体运行时而产生的。

例如:父进程通过fork ()程序创建一个子进程。

4.进程控制如何实现的?举例说明。

答:进程控制一般由OS的内核中的原语来实现的。

例如:用完了I/O设备的进程调用原语weakup(),将等待该事件的进程唤醒。

5.进程通信方式各有什么特点?用程序及运行结果举例说明。

相关文档
最新文档