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

合集下载

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

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

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

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

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

一、进程管理的基本概念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()在输出字符串时不会被中断。

实验三-进程通讯实验报告

实验三-进程通讯实验报告

实验三进程通讯实验报告【姓名】【学号】【实验题目】进程通讯——消息队列与共享存储区【实验目的】(1)掌握进程间通讯的编程方法;(2)加深对进程并发执行的理解;(3)学习利用消息队列和共享存储区实现进程通信的方法。

【实验内容】设计一个多进程并发运行的程序,它由不同的进程完成下列工作:(1)接收键盘输入进程负责接收用户的键盘输入,并以适当的方式将由键盘获得的数据交给其它进程处理。

(2)显示进程负责全部数据显示任务,包括键盘输入数据的显示和提示信息的显示。

(3)分发数据进程将键盘输入的数据分为3类,即字母、数字和其它,并分别将字母写入文件letter.txt 中,数字写入文件number.txt中,除字母和数字外其它数据丢弃。

【实验要求】1、程序能以适当的方式提示用户输入数据;2、提示用户有数据被丢弃;3、全部的显示任务必须由显示进程完成;4、整个程序能够连续处理多组输入数据,直到用户输入“quit”字符串,整个程序结束;5、进一步要求:同时采用共享存储区和消息2种方法实现进程之间的通信,并比较这2种通信方法的利弊。

【实验方法】1、利用fork()函数创建2个子进程,用一个父进程和两个子进程完成上面的三个实验任务,用子进程1实现分发数据任务,子进程2实现接受键盘输入任务,父进程实现全部的显示任务。

2、同时通过共享存储区和消息队列两种进程通讯方式实现上面三个进程之间的同步和互斥。

3、利用while()循环、kill()函数和signal()函数实现连续多组数据输入。

【程序结构】·数据结构:消息队列、字符数组;·程序结构:顺序结构、if-else分支结构和while循环结构;·主要算法:无特别算法【实验结果】1、有代表性的执行结果:[stud13@localhost stud13]$ cc ipc.c[stud13@localhost stud13]$ ./a.outPlease input a line:∟operatingsystem01234-=,.Your message is:operatingsystem01234-=,.The characters deserted are:-=,.Please input a line:∟xushengju6651001!@#$%^&*()Your message is:xushengju6651001!@#$%^&*()The characters deserted are:!@#$%^&*()Please input a line:∟Hello123Your message is:Hello123Please input a line:∟quit[stud13@localhost stud13]$ cat letter.txtOperatingsystemxushengjuHello[stud13@localhost stud13]$ cat number.txt 012346651001123[stud13@localhost stud13]$2、结果分析及解释:在创建子进程1时,由于先返回子进程的ID号,msgrcv(msgid,&msg,BUFSIZE,0,0)一直都是非0值,故循环等待。

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

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

实验三进程管理及进程通信实验环境: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,编写程序。

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

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

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

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

操作系统-进程管理实验报告实验一进程管理1.实验目的:(1)加深对进程概念的理解,明确进程和程序的区别;(2)进一步认识并发执行的实质;(3)分析进程争用资源的现象,研究解决进程互斥的方法;(4)了解Linux系统中进程通信的基本原理。

2.实验预备内容(1)阅读Linux的sched.h源码文件,加深对进程管理概念的理解;(2)阅读Linux的fork()源码文件,分析进程的创建过程。

3.实验内容(1)进程的创建:编写一段程序,使用系统调用fork()创建两个子进程。

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

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

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

源代码如下:#include<XXX>#include<XXX>#include<unistd.h>#include <XXX>#include <XXX>int main(int argc,char* argv[]){pid_t pid1,pid2;pid1 = fork();if(pid1<0){fprintf(stderr,"childprocess1 failed");exit(-1);}else if(pid1 == 0){printf("b\n");}else{pid2 = fork();if(pid2<0){fprintf(stderr,"childprocess1 failed"); exit(-1);}else if(pid2 == 0){printf("c\n");}else{printf("a\n");sleep(2);exit(0);}}return 0;}结果如下:分析原因:pid=fork();操纵体系创建一个新的历程(子历程),而且在历程表中相应为它建立一个新的表项。

进程管理实验报告分析(3篇)

进程管理实验报告分析(3篇)

第1篇一、实验背景进程管理是操作系统中的一个重要组成部分,它负责管理计算机系统中所有进程的创建、调度、同步、通信和终止等操作。

为了加深对进程管理的理解,我们进行了一系列实验,以下是对实验的分析和总结。

二、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。

2. 进一步认识并发执行的实质。

3. 分析进程争用资源的现象,学习解决进程互斥的方法。

4. 了解Linux系统中进程通信的基本原理。

三、实验内容1. 使用系统调用fork()创建两个子进程,父进程和子进程分别显示不同的字符。

2. 修改程序,使每个进程循环显示一句话。

3. 使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号,实现进程的终止。

4. 分析利用软中断通信实现进程同步的机理。

四、实验结果与分析1. 实验一:父进程和子进程分别显示不同的字符在实验一中,我们使用fork()创建了一个父进程和两个子进程。

在父进程中,我们打印了字符'a',而在两个子进程中,我们分别打印了字符'b'和字符'c'。

实验结果显示,父进程和子进程的打印顺序是不确定的,这是因为进程的并发执行。

2. 实验二:每个进程循环显示一句话在实验二中,我们修改了程序,使每个进程循环显示一句话。

实验结果显示,父进程和子进程的打印顺序仍然是随机的。

这是因为并发执行的进程可能会同时占用CPU,导致打印顺序的不确定性。

3. 实验三:使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号在实验三中,我们使用signal()捕捉键盘中断信号(按c键),然后通过kill()向两个子进程发送信号,实现进程的终止。

实验结果显示,当按下c键时,两个子进程被终止,而父进程继续执行。

这表明signal()和kill()在进程控制方面具有重要作用。

4. 实验四:分析利用软中断通信实现进程同步的机理在实验四中,我们分析了利用软中断通信实现进程同步的机理。

进程通讯管理实验报告(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. 理解进程的基本概念和进程状态转换过程。

2. 掌握进程创建、进程同步和进程通信的方法。

3. 了解进程调度算法的基本原理和实现方法。

4. 通过实验加深对进程管理的理解,提高操作系统实践能力。

二、实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 开发工具:GCC三、实验内容1. 进程创建与状态转换(1)使用fork()函数创建一个子进程,并观察父进程和子进程的进程ID。

(2)使用exec()函数替换子进程的映像,实现进程的创建。

(3)观察进程状态转换过程,如创建、运行、阻塞、就绪、终止等。

2. 进程同步(1)使用互斥锁(mutex)实现进程的互斥访问共享资源。

(2)使用信号量(semaphore)实现进程的同步,如生产者-消费者问题。

(3)观察进程同步的效果,确保进程安全执行。

3. 进程通信(1)使用管道(pipe)实现进程间的单向通信。

(2)使用消息队列(message queue)实现进程间的双向通信。

(3)使用共享内存(shared memory)实现进程间的快速通信。

(4)观察进程通信的效果,确保数据正确传递。

(1)实现基于优先级的进程调度算法,如先来先服务(FCFS)和最高优先级优先(HPF)。

(2)实现基于时间片的轮转调度算法(RR)。

(3)观察进程调度算法的效果,分析不同算法的优缺点。

四、实验步骤1. 编写程序实现进程创建与状态转换,使用fork()和exec()函数。

2. 编写程序实现进程同步,使用互斥锁和信号量。

3. 编写程序实现进程通信,使用管道、消息队列和共享内存。

4. 编写程序实现进程调度,使用优先级调度和时间片轮转调度。

5. 编译并运行程序,观察实验结果,分析实验现象。

五、实验结果与分析1. 进程创建与状态转换通过实验,我们成功创建了父进程和子进程,并观察到进程ID的变化。

在进程创建过程中,父进程的进程ID与子进程的进程ID不同,说明子进程是独立于父进程的实体。

实验四 进程通信

实验四 进程通信

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

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

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

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

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

在发送时,指定接收方的地址或标识,也可以指定多个接收方或广播式地址, send(Receiver, message)。

在接收时,允许接收来自任意发送方的消息,并在读出消息的同时获取发送方的地址, receive(Sender,message)。

b. 间接通信:借助于收发双方进程之外的共享数据结构作为通信中转,如消息队列。

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

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

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

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

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

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

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

实验 进程管理进程通信PPT课件

实验 进程管理进程通信PPT课件

main()
{ int k,p1;
while((p1=fork())==-1);
//创建子进程
if(p1>0)
//父进程返回
{ for(k=1;k<4;k++) //显示3行信息
{ printf("How are you !\n");
sleep(1);
}
kill(p1,12); //发软中断信号给子进程
10
[例] 父子进程同步要求如下: 父进程创建一个子进程,在父进程中显示3行"How are you ! "然后发软中断信号给子进程,再等待子 进程终止后输出结束信息"OK!",然后终止执行。 子进程中循环显示"I'm child" ,当接收到父进程发 来的软信号后停止循环,显示"Child exited! "并终 止执行。
1
2
Linux进程低级通信
Linux提供了同步、互斥及软中断的系统调用/库函数:
lockf(fd,function,size) 可用于互斥 fcntl 文件控制函数(根据文件描述词来操作文件的特性)。 wait() 用于父子进程间的同步 sleep(n) 使当前进程睡眠n秒后自动唤醒自己 kill(pid,sig)传递软中断信号 signal(sig,func)接收软中断信号
演讲人:XXXXXX 时 间:XX年XX月XX日
4
发送软中断信号函数
int kill ( pid , sig )
pid——表示一个或一组进程的标识符: 当pid>0时,将信号发送给指定pid的进程; 当pid=0时,将信号发送给同组的所有进程; 当pid=-1时,将信号发送给以下所有满足条件的进程:该进 程用户标识符等于发送进程有效用户标识符; sig——软中断信号的序号或名称

操作系统实验_实验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查看以上程序执行过程。

实验四 进程通信实验

实验四 进程通信实验

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

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

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

进程管理实验报告【姓名】…【学号】…【实验题目】进程管理【实验目的】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!而父进程则从管道中读出来自两个子进程的信息,显示在屏幕上。

进程控制与进程通信程序实验报告

进程控制与进程通信程序实验报告

进程控制与进程通信程序实验报告进程控制与进程通信程序实验报告本次实验主要涉及进程控制和进程通信两个方面。

进程控制是指操作系统对进程的管理和控制,包括创建、撤销、挂起、恢复等操作。

进程通信是指进程之间进行信息交换的过程,包括共享内存、管道、消息队列等方式。

在本次实验中,我们使用了C语言编写了两个程序,一个是父进程程序,一个是子进程程序。

父进程程序通过fork()函数创建子进程,然后通过wait()函数等待子进程结束。

子进程程序则通过exec()函数执行另一个程序。

这个程序是一个简单的计算器程序,可以进行加减乘除运算。

在进程通信方面,我们使用了共享内存的方式进行进程间通信。

共享内存是指多个进程共享同一块内存空间,可以实现进程间的数据共享。

在本次实验中,我们使用了shmget()函数创建共享内存,shmat()函数将共享内存映射到进程的地址空间中,shmdt()函数将共享内存从进程的地址空间中分离,shmctl()函数控制共享内存的状态。

在父进程程序中,我们使用了共享内存来传递两个操作数和操作符。

父进程程序首先创建共享内存,然后将两个操作数和操作符写入共享内存中。

子进程程序通过共享内存读取这些数据,并进行相应的计算。

计算结果再通过共享内存传递回父进程程序,父进程程序读取共享内存中的结果并输出。

本次实验的结果表明,进程控制和进程通信是操作系统中非常重要的概念。

掌握了这些概念,可以更好地理解操作系统的工作原理,也可以更好地编写高效的程序。

同时,共享内存是一种非常实用的进程通信方式,可以在多个进程之间实现数据共享,提高程序的效率。

总之,本次实验让我们更深入地了解了进程控制和进程通信的概念和实现方式。

通过编写程序,我们掌握了fork()、wait()、exec()、shmget()、shmat()、shmdt()、shmctl()等函数的使用方法,也更好地理解了操作系统的工作原理。

实验进程管理实验报告

实验进程管理实验报告

一、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。

2. 进一步认识并发执行的实质,理解进程的创建、调度、同步与通信。

3. 学习使用Linux系统中的进程管理命令,掌握进程的监控、控制与优化。

二、实验环境操作系统:Linux Ubuntu 20.04实验工具:终端(Terminal)、shell命令三、实验内容1. 进程的基本概念与特性2. 进程的创建与调度3. 进程同步与通信4. 进程的监控与优化四、实验步骤1. 进程的基本概念与特性(1)通过阅读相关资料,了解进程的概念、特性和生命周期。

(2)使用shell命令查看当前系统中进程的状态,如ps、top、htop等。

2. 进程的创建与调度(1)使用fork()函数创建进程,观察父子进程之间的关系。

(2)使用exec()函数替换子进程的映像,实现进程的创建。

(3)使用wait()、waitpid()等函数等待子进程结束,控制进程执行顺序。

(4)通过修改进程优先级,观察进程调度策略的变化。

3. 进程同步与通信(1)使用互斥锁(mutex)实现进程同步,防止数据竞争。

(2)使用条件变量(condition variable)实现进程间的条件同步。

(3)使用信号量(semaphore)实现进程间的同步与通信。

(4)通过管道(pipe)、消息队列(message queue)、共享内存(shared memory)等机制实现进程间的通信。

4. 进程的监控与优化(1)使用ps、top、htop等命令监控进程的运行状态。

(2)通过调整进程优先级,优化进程的执行顺序。

(3)使用renice命令调整进程的实时性。

(4)使用nice命令调整进程的调度策略。

五、实验结果与分析1. 进程的基本概念与特性通过实验,我们了解到进程是具有一定独立功能的程序关于某个数据集合的一次运行活动,具有并发性、动态性、独立性、异步性和结构特征等特性。

2. 进程的创建与调度实验过程中,我们成功创建了多个进程,并通过修改进程优先级,观察到调度策略的变化。

进程控制与进程通信程序实验报告

进程控制与进程通信程序实验报告

进程控制与进程通信程序实验报告1. 背景进程控制与进程通信是操作系统的重要概念之一,它们在现代计算机系统中起到了至关重要的作用。

进程控制是指操作系统对进程的创建、执行、中止和切换等各种操作的管理和控制,进程通信则是指进程之间通过各种方式传递信息和实现协作的机制。

在本次实验中,我们需要编写一个进程控制与进程通信程序。

通过实现进程的创建、执行和中止等基本操作,并通过进程通信机制进行信息传递,实现多个进程之间的协作。

本实验将帮助我们进一步理解和掌握进程控制与进程通信的原理和操作。

2. 分析2.1 实验要求本次实验要求我们编写一个进程控制与进程通信程序,实现以下功能:1.创建一个主进程和多个子进程,并实现进程的执行和切换;2.子进程之间通过进程通信机制传递信息;3.实现多个子进程之间的协作,完成指定的任务。

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

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

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

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

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

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

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

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

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

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

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

进程管理_实验报告

进程管理_实验报告

一、实验目的1. 理解Linux操作系统中进程的概念,明确进程与程序的区别。

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

3. 学会使用Linux命令查看和管理进程。

二、实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 开发工具:gcc、gdb三、实验内容1. 进程创建与调度2. 进程同步与互斥3. 进程通信4. 进程控制四、实验步骤1. 进程创建与调度(1)编写一个C程序,创建一个子进程,并在父进程中打印出子进程的进程标识符(PID)。

```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>int main() {pid_t pid;pid = fork(); // 创建子进程if (pid == 0) { // 子进程printf("子进程的PID:%d\n", getpid());} else if (pid > 0) { // 父进程printf("父进程的PID:%d,子进程的PID:%d\n", getpid(), pid); } else {printf("创建子进程失败\n");}return 0;}```(2)编译并运行程序,观察结果。

2. 进程同步与互斥(1)编写一个C程序,使用互斥锁(mutex)实现两个进程的同步。

```c#include <stdio.h>#include <stdlib.h>#include <pthread.h>pthread_mutex_t mutex;void thread_func(void arg) {pthread_mutex_lock(&mutex); // 获取互斥锁printf("线程 %ld 获取了互斥锁\n", pthread_self());sleep(1);pthread_mutex_unlock(&mutex); // 释放互斥锁return NULL;}int main() {pthread_t thread1, thread2;pthread_mutex_init(&mutex, NULL); // 初始化互斥锁pthread_create(&thread1, NULL, thread_func, (void )1);pthread_create(&thread2, NULL, thread_func, (void )2);pthread_join(thread1, NULL);pthread_join(thread2, NULL);pthread_mutex_destroy(&mutex); // 销毁互斥锁return 0;}```(2)编译并运行程序,观察结果。

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

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

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

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

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

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

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

操作过程及结果:实验1:编写程序.显示进程的有关标识(进程标识、组标识、用户标识等)。

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

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

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

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

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

实验3:编写程序。

父进程通过循环语句创建若干子进程.探讨进程的家族树以及子进程继承父进程的资源的关系。

结果:思考:①画出进程的家族树。

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

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

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

答2:#include 〈stdio.h〉#include <sys/types.h〉#include <unistd.h〉main(){int i, pid;for (i=1; i〈4; i++)if (pid=fork()) break;}实验4:编写程序.使用fork( )和exec( )等系统调用创建三个子进程。

实验2进程与进程通信(网络)全

实验2进程与进程通信(网络)全
例:在当前目录中执行program程序 ./program 如不打入./ 那么要修改用户登录目录的配置文件 .bash_profile 中的环境变量$PATH: PATH=$PATH:.
先编一个最简单的程序,并编译执行
void main() {
printf(“Welcome to Unix\n〞); }
最简单的vi命令
vi filename.c i(或a) 在光标之前(或之后)插入 o(或O) 在当前行下(或上)面插入 BACKSPACE(或DELETE)键删除 ESC键退出插入状态
^F (Fowlow) 下移一屏
^B (Back) 上移一屏
x
删除光标位置的一个字符
dd 删除当前行
:wq 保存文件后退出vi
〔三〕实验报告要求
要求在实验室当场调试完成,经教师检查通过, 登记,实验报告可免做。
对于因情况,不能到实验室上机的同学,可在自 己的Linux机器上机,但要求写实验报告,包括 题目、数据构造的说明,画出程序框图,在源 程序中参加注释,说明程序的测试方法和测试 结果,以及实验总结和体会〔可多可少〕。
实验二 进程和进程通信
〔一〕实验目的
通过使用进程和进程通信方面的系统调 用的,加深理解有关进程方面的根本概 念。通过实验对进程有进一步的感性认 识,掌握系统V的IPC机制。
〔二〕实验题目
1.设计一个程序,创立一个子进程,使父子进程合 作,协调地完成某一功能。要求在该程序中还要 使用进程的睡眠、进程图象改换、父进程等待子 进程终止、信号的设置与传送〔包括信号处理程 序〕、子进程的终止等有关进程的系统调用。
把源程序、实验结果、报告做成一个word文件, 在文件里有1~2张含有本人姓名〔可汉语拼音〕 和学号的上机界面截图
  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:编写程序。

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

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

结果:思考:①画出进程的家族树。

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

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

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

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

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

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

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

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

结果:思考:子进程运行其它程序后,进程运行环境怎样变化的?反复运行此程序看会有什么情况?解释一下。

答:子进程运行其他程序后,这个进程就完全被新程序代替。

由于并没有产生新进程所以进程标识号不改变,除此之外的旧进程的其他信息,代码段,数据段,栈段等均被新程序的信息所代替。

新程序从自己的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()函数,然后打印“子进程已经结束”,一旦子进程结束,父进程撤销进程。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

答:通信方式有:(1)共享存储器系统:相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。

(2)消息传递系统:源程序可以直接或间接地将消息传送给目标进程。

(3)管道通信系统:能够连接一个写进程和一个读进程、并允许它们以生产者-消费者方式进行通信的一个共享文件,又称为pipe文件。

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

6.管道通信如何实现?该通信方式可以用在何处?答:实现:(1)互斥,即当一个进程正在对pipe执行读/写操作时其它进程必须等待;(2)同步,指当写(输入)进程把一定数量的数据写入pipe时,便去睡眠等待,知道读(输出)进程取走数据后,再把它唤醒。

当读进程读一空pipe时,也应睡眠等待,直至写进程将数据写入管道后,才将之唤醒;(3)确定对方是否存在,只有确定了对方已存在时,才能进行通信。

用法:用于链接一个读进程和一个写进程以实现它们之间的通信的一个共享文件。

7.什么是软中断?软中断信号通信如何实现?答:每个信号读对应一个正整数常量,代表同一用户的诸进程之间传送事先约定的信息的类型,用于通知某进程发生了某一场时间。

每个进程在运行时,都要通过信号量机制来检查是否有信号到达。

若有,便中断正在执行的程序,转向与该信号对应的处理程序,以完成对该事件的处理,处理结束后再返回到原来的断电继续执行。

实质上,信号机制是对中断机制的一种模拟。

体会:在本次实验中,我利用Linux提供的系统调用设计程序,加深了对进程概念的理解,也体会到了系统进程调度的方法和效果,还了解了进程之间的通信方式以及各种通信方式的使用。

虽然在实验的过程中遇到很多困难,但是还好有张涛老师的悉心指点和网上资料的帮助,使我能渡过难关,圆满完成本次实验,在此也向他们说一声感谢。

附录:(源程序)1、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <wait.h>int main(void){printf("process id:%d\n",getpid());printf("process group id:%d\n",getpgrp());printf("calling process's real user id = %d\n",getuid());sleep(5);int child_pid;child_pid = fork();if(child_pid == 0){exit(1);}wait(0);printf("Do you want to stop the process?\n");char x;scanf("%c",&x);if(x == 'y')exit(0);return 0;}2、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <wait.h>int main(){int i;if (fork()){i = wait(0);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(0);}}3、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <wait.h>int main(void){int i,j;printf("My pid is %d, my father’s pid is %d\n",getpid() ,getppid());for(i=0; i<3; i++)if(fork()==0)printf("%d pid=%d ppid=%d\n", i,getpid(),getppid());else{j=wait(0);printf("%d:The chile %d is finished.\n",getpid(),j);}}4、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <wait.h>int main(void){int child_pid1,child_pid2,child_pid3;int pid,status; setbuf(stdout,NULL);child_pid1=fork();if(child_pid1==0){execlp("echo","echo","child process 1",(char *)0);perror("exec1 error.\n ");exit(1);}child_pid2=fork();if(child_pid2==0){execlp("date","date",(char *)0);perror("exec2 error.\n "); exit(2);}child_pid3=fork();if(child_pid3==0){execlp("ls","ls",(char *)0);perror("exec3 error.\n ");exit(3);}puts("Parent process is waiting for chile process return!");while((pid=wait(&status))!=-1){if(child_pid1==pid)printf("child process 1 terminated with status %d\n",(status>>8));else{if(child_pid2==pid)printf("child process 2 terminated with status %d\n",(status>>8));else{if(child_pid3==pid)printf("child process 3 terminated with status %d\n" ,(status>>8));}}}puts("All child processes terminated.");puts("Parent process terminated.");exit(0);}5、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include<sys/types.h>int globa=4;int main(void){pid_t pid;int vari=5;printf("before fork.\n");if ((pid=fork())<0){printf("fork error.\n");exit(0);}elseif(pid==0){globa++;vari--;printf("Child %d changed the vari and globa.\n",getpid());}elseprintf("Parent %d did not changed the vari and globa.\n",getpid());printf("pid=%d, globa=%d, vari=%d\n",getpid(),globa,vari);exit(0);}6、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <wait.h>int main(void){int i,r,j,k,l,p1,p2,fd[2];char buf[50],s[50];pipe(fd);while((p1=fork())==-1);if(p1==0){lockf(fd[1],1,0);sprintf(buf,"Child process P1 is sending messages! \n");printf("Child process P1! \n");write(fd[1],buf,50); lockf(fd[1],0,0);sleep(5);j=getpid();k=getppid();printf("P1 %d is weakup. My parent process ID is %d.\n",j,k);exit(0);}else{while((p2=fork())==-1);if(p2==0){lockf(fd[1],1,0);sprintf(buf,"Child process P2 is sending messages! \n");printf("Child process P2! \n"); write(fd[1],buf,50); lockf(fd[1],0,0);sleep(5);j=getpid();k=getppid();printf("P2 %d is weakup. My parent process ID is %d.\n",j,k);exit(0);}else{l=getpid();wait(0);if(r=read(fd[0],s,50)==-1)printf("Can't read pipe. \n");elseprintf("Parent %d: %s \n",l,s);wait(0);if(r=read(fd[0],s,50)==-1)printf("Can't read pipe. \n");elseprintf("Parent %d: %s \n",l,s);exit(0);}}}7、8、服务器程序:#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <wait.h>#include<sys/ipc.h>#include<sys/msg.h>#define MSGKEY 75struct msgform{long mtype;char mtext[256];}msg;int msgqid;int main(){int i,pid,* pint;extern cleanup();for(i=0;i<20;i++)signal(i,cleanup);msgqid=msgget(MSGKEY,0777|IPC_CREAT);for(;;){msgrcv(msgqid,&msg,256,1,0);pint=(int *)msg.mtext;pid=*pint;printf("Server :receive from pid %d\n",pid);msg.mtype=pid;*pint=getpid();msgsnd(msgqid,&msg,sizeof(int),0);}}cleanup(){msgctl(msgqid,IPC_RMID,0);exit(0);}客户端程序:#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <wait.h>#include<sys/ipc.h>#define MSGKEY 75struct msgform{long mtype;char mtext[256];};int main(void){struct msgform msg;int msgqid,pid,*pint;msgqid=msgget(MSGKEY,0777);pid=getpid();pint=(int *)msg.mtext;*pint=pid;msg.mtype=1;msgsnd(msgqid,&msg,sizeof(int),0);msgrcv(msgqid,&msg,256,pid,0);printf("Clint : receive from pid %d\n",* pint);}9、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <wait.h>#include<sys/ipc.h>#include<sys/msg.h>#define MSGKEY 75int main(void){int i,j,k;int func();signal(18,func());if(i=fork()){j=kill(i,18);printf("Parent: signal 18 has been sent to child %d,returned %d.\n",i,j);k=wait(0);printf("After wait %d,Parent %d: finished.\n",k,getpid());}else{printf("Child %d: A signal from my parent is recived.\n",getpid());}}func(){int m;m=getpid();printf("I am Process %d: It is signal 18 processing function.\n",m);}10、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include <signal.h>#define N 5 // 消费者或者生产者的数目#define M 10 // 缓冲数目int in = 0; // 生产者放置产品的位置int out = 0; // 消费者取产品的位置int buff[M] = { 0 }; // 缓冲初始化为0,开始时没有产品sem_t empty_sem; // 同步信号量,当满了时阻止生产者放产品sem_t full_sem; // 同步信号量,当没产品时阻止消费者消费pthread_mutex_t mutex; // 互斥信号量,一次只有一个线程访问缓冲int product_id = 0; //生产者id int prochase_id = 0; //消费者id//信号处理函数void Handlesignal(int signo){printf("程序退出\n",signo);exit(0);}/* 打印缓冲情况*/void print() {inti;printf("产品队列为");for(i = 0; i < M; i++)printf("%d", buff[i]);}/* 生产者方法*/void *product() {int id = ++product_id;while(1) {//重复进行//用sleep的数量可以调节生产和消费的速度,便于观察sleep(2);sem_wait(&empty_sem);pthread_mutex_lock(&mutex);in= in % M;printf("生产者%d在产品队列中放入第%d个产品\t",id, in);buff[in]= 1;print();++in;pthread_mutex_unlock(&mutex);sem_post(&full_sem);}}/* 消费者方法*/void *prochase() {intid = ++prochase_id;while(1) {//重复进行//用sleep的数量可以调节生产和消费的速度,便于观察sleep(5);sem_wait(&full_sem);pthread_mutex_lock(&mutex);out= out % M;printf("消费者%d从产品队列中取出第%d个产品\t",id, out);buff[out]= 0;print();++out;pthread_mutex_unlock(&mutex);sem_post(&empty_sem);}}int main() {printf("生产者和消费者数目都为5,产品缓冲为10,生产者每2秒生产一个产品,消费者每5秒消费一个产品,Ctrl+退出程序\n");pthread_tid1[N];pthread_tid2[N];inti;intret[N];//结束程序if(signal(SIGINT,Handlesignal)==SIG_ERR){//按ctrl+C产生SIGINT信号printf("信号安装出错\n");}// 初始化同步信号量intini1 = sem_init(&empty_sem, 0, M);//产品队列缓冲同步intini2 = sem_init(&full_sem, 0, 0);//线程运行同步if(ini1 && ini2 != 0) {printf("信号量初始化失败!\n");exit(1);}//初始化互斥信号量intini3 = pthread_mutex_init(&mutex, NULL);if(ini3 != 0) {printf("线程同步初始化失败!\n");exit(1);}// 创建N个生产者线程for(i = 0; i < N; i++) {ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));if(ret[i] != 0) {printf("生产者%d线程创建失败!\n", i);exit(1);}}//创建N个消费者线程for(i = 0; i < N; i++) {ret[i]= pthread_create(&id2[i], NULL, prochase, NULL);if(ret[i] != 0) {printf("消费者%d线程创建失败!\n", i);exit(1);}}//等待线程销毁for(i = 0; i < N; i++) {pthread_join(id1[i], NULL);pthread_join(id2[i],NULL);}exit(0);}。

相关文档
最新文档