北邮-大三-操作系统-进程管理实验报告

合集下载

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

操作系统实验报告

操作系统实验报告

实验名称:操作系统进程管理实验实验目的:1. 理解操作系统进程管理的概念和原理。

2. 掌握进程的创建、调度、同步和通信机制。

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

实验环境:1. 操作系统:Windows 102. 编程语言:C/C++3. 开发环境:Visual Studio实验内容:一、实验一:进程的创建与终止1. 实验目的了解进程的创建和终止机制,掌握进程控制块(PCB)的结构和功能。

2. 实验步骤(1)创建一个进程,使用系统调用创建子进程;(2)设置子进程的属性,如优先级、名字等;(3)终止子进程,释放资源;(4)查看进程信息,确认进程创建和终止过程。

3. 实验代码```c#include <stdio.h>#include <sys/types.h>#include <unistd.h>int main() {pid_t pid;printf("Parent process: %d\n", getpid());pid = fork(); // 创建子进程if (pid == 0) {printf("Child process: %d\n", getpid());printf("Child process is running...\n");sleep(5); // 子进程延时5秒exit(0);} else {printf("Child process created: %d\n", pid);wait(NULL); // 等待子进程结束printf("Child process terminated.\n");}return 0;}```4. 实验结果在运行实验代码后,首先输出父进程的进程号,然后输出子进程的进程号,子进程运行5秒后结束,父进程输出子进程终止信息。

北京邮电大学 操作系统实验 实验报告

北京邮电大学 操作系统实验 实验报告

操作系统实验实验报告实验日期:11月23日实验名称:实验一一、实验目的1.学习LINUX操作系统2.熟悉UNIX/LINUX的常用基本命令3.理解fork()与clone()函数的区别和联系4.深入理解生产者和消费者问题二、实验内容(1)安装LINUX:(2)熟悉UNIX/LINUX的常用基本命令如ls、who、wc、pwd、ps、pstree、top,cat,cd,chgrp,chmod,chown,comm,cmp,cp,rm,diff,mv,rmdir等,了解环境。

(3)比较fork()和clone()的功能,利用fork()生成子进程和clone()生成线程。

(4)利用pthread库,通过其中的mutex来实现生产者和消费者问题。

三、项目要求及分析基本要求:(1)安装LINUX:使用FEDORA11(2)熟悉UNIX/LINUX的常用基本命令如ls、who、wc、pwd、ps、pstree、top,cat,cd,chgrp,chmod,chown,comm,cmp,cp,rm,diff,mv,rmdir等,了解环境。

(3)比较fork()和clone()的功能,利用fork()生成子进程和clone()生成线程。

(4)利用pthread库,通过其中的mutex来实现生产者和消费者问题。

四、具体实现1.linux常用指令1.1 目录操作和DOS 相似,Linux 采用树型目录管理结构,由根目录开始一层层将子目录建下去,各子目录以“/”隔开。

用户login后,工作目录的位置称为home directory,由系统管理员设定。

‘—’符号代表自己的home directory,例如:~/myfile是指自己home目录下myfile这个文件。

Linux 的通配符有三种:‘*’和‘?’用法与DOS相同,‘’代表区间内的任一字符,如test[05]即代表test0,test1,……,test5的集合。

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

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

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

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

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

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

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

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

源代码如下:#include<sys/types.h>#include<stdio.h>#include<unistd.h>#include <fcntl.h>#include <errno.h>int main(int argc,char* argv[]){pid_t pid1,pid2;pid1 = fork();if(pid1<0){fprintf(stderr,"childprocess1 failed");exit(-1);}1/12else 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();操作系统创建一个新的进程(子进程),并且在进程表中相应为它建2/12立一个新的表项。

进程管理实验报告分析(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. 实验四:分析利用软中断通信实现进程同步的机理在实验四中,我们分析了利用软中断通信实现进程同步的机理。

北邮操作系统进程同步实验报告与源代码

北邮操作系统进程同步实验报告与源代码

北邮操作系统进程同步实验报告与源代码进程管理实验报告1.实验目的:(1)理解进程/线程同步的方法,学会运用进程/线程同步的方法解决实际问题;(2)了解windows系统或unix/linux系统下中信号量的使用方法。

2.实验内容编写一个有关生产者和消费者的程序:每个生产者每次生产一个产品存入仓库,每个消费者每次从仓库中取出一个产品进行消费,仓库大小有限,每次只能有一个生产者或消费者访问仓库。

要求:采用信号量机制。

3、环境说明本实验是在win7环境下使用dev编译器实现的,采用Win API的信号量机制。

4、程序设计说明该程序根据教材中的消费者生产者问题编写的,使用了教材中提供的框架思路以及库函数,使用CreateThread建立新的线程,使用CreateMutex 创建一个互斥信号量,使用CreateSemaphore创建信号量,使用ReleaseMutex释放线程的互斥信号量,使用ReleaseSemaphore对指定的信号量增加指定的值,使用WaitForSingleObject等待空位,使用CloseHandle在操作结束后关闭线程和信号量。

在这个程序里我设计了三个函数:Int main()是主函数,其中包含了缓冲区大小的设置,生产者消费者发出请求等内容以及线程创建等内容DWORD WINAPI producer(LPVOID lpPara)是生产者等待缓冲区的使用权并对缓冲区进行操作DWORD WINAPI consumer(LPVOID lpPara)是消费者等待缓冲区的使用权并对缓冲区进行操作该程序模拟生产者消费者问题,首先要设置缓冲区的大小,输入请求资源的各个进程的信息以及请求时间,并且按照请求时间对各进程进行排序,创建线程,然后按序依次对缓冲区进行操作,详细设计见源代码。

5、程序运行结果截图:只有生产者请求,没有消费者请求,请求满足只有消费者请求,没有生产者请求,消费者的请求不成功:生产者请求大于消费者请求并且消费者请求在生产者放入产品之后:消费者请求多于生产者请求,只能满足部分消费者请求,不能满足全部:6、源代码:#include#include#include#include#include#includeusing namespace std;#define MAX_BUF 1000#define MAX_REQ 20HANDLE mutex;HANDLE full;HANDLE empty;HANDLE thread[MAX_REQ]; DWORD pro_id[MAX_REQ]; DWORD con_id[MAX_REQ]; struct request{int type;//记录生产者消费者的类型int seq; //记录请求次序}req[MAX_REQ];int buf_size;int req_size;int no;int buffer[MAX_BUF];int in;int out;int result;bool cmp(request a,request b){ return a.seqDWORD WINAPI producer(LPVOID lpPara){WaitForSingleObject(full,INFINITE);WaitForSingleObject(mutex,INFINITE);printf("生产者%d将第%d号产品放入缓冲区……\n",(int)lpPara,no);buffer[in]=no++;in=(in+1)%buf_size;printf("成功放入缓冲区!\n\n",(int)lpPara);ReleaseMutex(mutex);ReleaseSemaphore(empty,1,NULL);return 0;}DWORD WINAPI consumer(LPVOID lpPara){WaitForSingleObject(empty,INFINITE);WaitForSingleObject(mutex,INFINITE);printf("消费者%d将第%d号产品从缓冲区取出……\n",(int)lpPara,buffer[out]);buffer[out]=0;printf("成功从缓冲区取出!\n\n",(int)lpPara);ReleaseMutex(mutex);out=(out+1)%buf_size;ReleaseSemaphore(full,1,NULL);return 0;}int main(){int i;int p=0;no = 1;in=out=0;memset(buffer, 0, sizeof(buffer));printf("请设置缓冲区大小:");scanf("%d",&buf_size);printf("请输入请求使用资源进程的个数:");scanf("%d",&req_size);for(i=0;iprintf("请选择是消费者进程(0)还是生产者进程(1):");scanf("%d",&req[i].type);printf("请输入该进程的请求时间:");scanf("%d",&req[i].seq);}sort(req,req+req_size,cmp);mutex=CreateMutex(NULL,FALSE,NULL);full=CreateSemaphore(NULL,buf_size,buf_size,NULL);empty=CreateSemaphore(NULL,0,buf_size,NULL);for(i=0;i{if(req[i].type==0){thread[i]=CreateThread(NULL, 0, consumer, (LPVOID)i, 0, &con_id[i]); if(thread[i]==NULL)return -1;printf("\n消费者请求从缓冲区中取产品,请求时间为%d\n",req[i].seq);}if(req[i].type==1){thread[i]=CreateThread(NULL,0,producer,(LPVOID)i,0,&pro_id[i]);if(thread[i]==NULL)return -1;printf("\n生产者请求往缓冲区中放产品,请求时间为%d\n",req[i].seq);}}result = WaitForMultipleObjects(req_size, thread, TRUE, 500);if (result == WAIT_TIMEOUT)printf("\n请求不能被完全满足\n");elseprintf("\n能够满足所有请求\n");for(int i=0; iCloseHandle(thread[i]);CloseHandle(mutex);CloseHandle(full);CloseHandle(empty);system("pause");return 0;}7、实验总结:本次实验基于书上的生产者消费者问题,原理在上课的时候老师已经详细地讲解过,但是在具体编程实现的过程中也遇到了很多问题,除了书上的库函数之外还有一些函数书上并没有给出用法,比如如何创建线程等函数,通过查阅参考相关资料解决,通过编写代码也系统地理解了生产者消费者问题的操作过程,线程的创建,信号量的创建以及信号量的使用方法等情况,遇到的好多编代码上的细节问题通过反复调试解决,有较大收获。

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

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

实验内容:进程管理一、实验目的1、掌握Linux中进程的创建方法及执行情况;2、加深对进程、进程树等概念的理解;3、掌握Linux中如何加载子进程自己的程序;4、掌握父进程通过创建子进程完成某项任务的方法;5.、掌握系统调用exit()和_exit()调用的使用。

6、分析进程竞争资源的现象,学习解决进程互斥的方法;进一步认识并发执行的实质二、实验内容(一)进程的创建1、编写一段程序,使用系统调用fork( )创建两个子进程。

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

让每一个进程在屏幕上显示一个字符。

#include<stdio.h>main(){int p,x;p=fork();if(p>0){x=fork();if(x>0)printf("father\n");elseprintf("child2");}elseprintf("child1");}输出结果:child1child2father2、运行以下程序,分析程序执行过程中产生的进程情况。

#include <stdio.h>main(){int p,x;p=fork();if (p>0)fork();else{fork();fork();}sleep(15);}实验步骤:编译连接gcc –o forktree forktree.c后台运行./forktree &使用pstree –h 查看进程树运行结果:├─gnom e-terminal─┬─bash─┬─forktree─┬─forktree─┬─forkt ree───forktree││││└─forktree│││└─forktree││└─pstree 分析:程序运行,系统首先创建一个进程forktree,执行到p=fork()创建一个子进程forktree,子进程获得处理机优先执行,父进程等待;执行else,当执行到第一个fork()函数时,子进程创建了一个进程forktree,称之为孙进程,孙进程获得处理机往下执行,子进程等待;执行到第二个fork()函数时,孙进程又创建一个进程forktree,称之为重孙进程,重孙进程很快执行完,将处理机还给孙进程,孙进程很快执行完,将处理机还给子进程;子进程继续往下执行,执行到第二个fork()函数,又创建一个进程forktree,称之为第二孙进程,并获得处理机执行,此进程很快执行完,将处理机还给子进程,子进程也很快执行完,将处理机还给父进程,父进程P>0执行if语句,运行fork()函数,又创建一个进程forktree,称之为第二子进程,此进程获得处理机执行很快运行完,将处理机还给父进程,父进程运行sleep(15)语句,休眠15秒,用pstree命令查询进程树。

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

操作系统实验报告-进程管理
2.进程的控制(随机执行以及加锁执行)
修改上述程序,将每个进程输出结果修改为每个进程输出几行字符(在此,如果为第一个子进程,则连续输出10行“the first child process”;如果为第二个子进程,则连续输出10行“the second child process”;如果为父进程,则连续输出10行“the parent process”),再观察程序的执行结果,并分析原因。然后,在上述程序中使用函数lockf()给每个进程加锁(锁定屏幕输出),从而实现进程之间互斥,观察并分析结果。
二、实验步骤及过程(可以附算法)
1.进入vi编辑器,创建test.c文件
2.输入代码如下;
3.输入gcc –o test test.c对test.c文件进行编译,输入./test对test.c文件进行执行,结果如下。
4.创建te.c文件
5.输入代码如下;
6.输入gcc –o te te.c对te.c文件进行编译,输入./te对te.c文件进行执行,结果如下。
实验名称:进程管理
组别:合作者:日期:5/24
一、预习:实验内容及要求
(实验目的:
1.加深对进程概念的理解,区分进程和程序的区别
2.进一步了解进程并发执行的本质
(2).实验内容:
1.创建进程
编写一段程序,使用函数fork()创建两个子进程,执行该程序时,在系统中同时存在一个父进程以及两个子进程活动。此时,让每个进程在屏幕上显示一个字符:父进程显示字符“p”;子进程分别显示字符“a”和字符“b”。请观察并记录程序的执行结果,并分析具体原因。
7.加入lockf()函数代码如下
8.再次编译并执行;
三、实验结果及分析(可另加附页)
通过本次实验了解了进程的进本操作,还有几个函数的基本调用,有fork()函数,lockf函数等等。

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

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

计算机与信息工程学院实验报告一、实验内容1.练习在shell环境下编译执行程序(注意:①在vi编辑器中编写名为sample.c的c语言源程序②用linux自带的编译器gcc编译程序,例如:gcc –o test sample.c③编译后生成名为test.out的可执行文件;④最后执行分析结果;命令为:./test)注意:linux自带的编译程序gcc的语法是:gcc –o 目标程序名源程序名,例如:gcc –o sample1 sample1.c,然后利用命令:./sample 来执行。

如果仅用“gcc 源程序名”,将会把任何名字的源程序都编译成名为a.out的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。

2.进程的创建仿照例子自己编写一段程序,使用系统调用fork()创建两个子进程。

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

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

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

3.分析程序实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。

二、实验步骤1. 利用fork()创建一个小程序(1)编写程序#include <sys/types.h>main (){int i=5;pid_t pid;pid=fork();for(;i>0;i--){if (pid < 0)printf("error in fork!");else if (pid == 0)printf("i am the child process, my process id is %d and i=%d\n",getpid(),i);elseprintf("i am the parent process, my process id is %d and i=%d\n",getpid(),i);}for(i=5;i>0;i--){if (pid < 0)printf("error in fork!");else if (pid == 0)printf("the child process, my process id is %d and i=%d\n",getpid(),i);elseprintf("the parent process, my process id is %d andi=%d\n",getpid(),i);}}(2)运行程序(3)分析程序在这里,主程序先运行,在屏幕上输出一个a,之后两个子程序分别运行而输出c和b。

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

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

操作系统进程管理实验报告一、引言在现代计算机科学中,操作系统的进程管理是确保系统高效运行的关键环节。

本实验旨在通过观察和分析操作系统的进程管理行为,深入理解进程的创建、运行和终止过程,以及操作系统如何对进程进行调度和资源分配。

二、实验目标1、理解进程的基本概念、进程状态及转换。

2、掌握进程的创建、终止和调度方法。

3、观察和分析进程在运行过程中的资源消耗和调度行为。

4、分析操作系统对进程的资源分配和调度策略对系统性能的影响。

三、实验环境与工具本实验在Linux操作系统上进行,使用GNU/Linux环境下的工具进行进程的创建、监控和调度。

四、实验步骤与记录1、创建进程:使用shell命令“fork”创建一个新的进程。

记录下父进程和子进程的PID,以及它们在内存中的状态。

2、进程状态观察:使用“ps”命令查看当前运行进程的状态,包括进程的PID、运行时间、CPU使用率等。

同时,使用“top”命令实时监控系统的CPU、内存等资源的使用情况。

3、进程调度:在“crontab”中设置定时任务,观察系统如何根据预设的调度策略分配CPU资源给各个进程。

4、资源分配:通过修改进程的优先级(使用“nice”命令),观察系统如何调整资源分配策略。

5、终止进程:使用“kill”命令终止一个进程,并观察系统如何处理该进程占用的资源。

五、实验结果与分析1、创建进程:通过“fork”系统调用,成功创建了一个新的进程,并获取了父进程和子进程的PID。

在内存中,父进程和子进程的状态分别为“running”和“ready”。

2、进程状态观察:使用“ps”命令可以看到父进程和子进程的状态均为“running”,同时显示了它们的CPU使用率和运行时间等信息。

通过“top”命令,可以实时监控系统的CPU、内存等资源的使用情况,为进一步分析提供了数据支持。

3、进程调度:在“crontab”中设置定时任务后,系统会根据预设的调度策略以及各个进程的运行状态,动态地分配CPU资源给各个进程。

(完整word版)北邮-大三-操作系统-进程管理实验报告

(完整word版)北邮-大三-操作系统-进程管理实验报告

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

2.实验预备内容(1)阅读Linux的sched。

h源码文件,加深对进程管理概念的理解;(2)阅读Linux的fork()源码文件,分析进程的创建过程。

3.实验内容(1)进程的创建:编写一段程序,使用系统调用fork()创建两个子进程.当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”.试观察记录屏幕上的显示结果,并分析原因.源代码如下:#include〈sys/types.h〉#include〈stdio.h>#include〈unistd。

h〉#include 〈fcntl。

h>#include 〈errno.h>1/17int 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”);}2/17else{printf("a\n”);sleep(2);exit(0);}}return 0;}结果如下:分析原因:pid=fork();操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。

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

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

操作系统进程管理实验报告操作系统进程管理实验报告引言:操作系统是计算机系统中最核心的软件之一,它负责管理计算机硬件和软件资源,提供良好的用户体验和高效的计算服务。

其中,进程管理是操作系统的重要功能之一,它负责管理和调度计算机中的各个进程,确保它们能够有序地运行,并且能够合理地利用计算机资源。

本实验旨在通过实际操作,深入了解操作系统的进程管理机制,并通过编写简单的进程管理程序,加深对进程管理的理解。

一、实验目的本实验的主要目的是通过编写简单的进程管理程序,加深对操作系统进程管理机制的理解。

具体来说,我们将实现以下功能:1. 创建进程:能够创建新的进程,并为其分配资源。

2. 进程调度:能够根据进程的优先级和调度算法,合理地调度进程的执行顺序。

3. 进程同步:能够实现进程间的同步与互斥,避免资源竞争和死锁问题。

二、实验环境和工具本实验使用的实验环境和工具如下:1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验过程和结果1. 进程创建在实验中,我们首先实现了进程的创建功能。

通过调用操作系统提供的系统调用接口,我们能够创建新的进程,并为其分配资源。

具体的实现过程涉及到进程控制块(PCB)的创建和初始化,以及资源的分配和管理。

通过编写测试程序,我们成功创建了多个进程,并验证了进程创建功能的正确性。

2. 进程调度进程调度是操作系统中非常重要的功能之一,它决定了进程的执行顺序和时间片的分配。

在实验中,我们实现了简单的进程调度算法,采用了轮转调度算法。

通过设计合适的数据结构和算法,我们能够按照一定的优先级和时间片大小,合理地安排进程的执行顺序。

通过编写测试程序,我们验证了进程调度功能的正确性。

3. 进程同步在多进程环境下,进程间的同步与互斥是非常重要的问题。

在实验中,我们实现了进程同步功能,通过使用信号量和互斥锁,实现了进程间的同步与互斥。

通过编写测试程序,我们验证了进程同步功能的正确性,并且能够避免资源竞争和死锁问题。

操作系统实验报告

操作系统实验报告

操作系统实验报告操作系统实验报告实验名称:进程管理实验实验目的:1. 了解进程的概念和特点;2. 掌握进程的创建、执行和退出等基本操作;3. 熟悉进程之间的同步和互斥机制;实验内容:1. 进程的创建:通过fork()函数创建子进程,并分别输出父进程和子进程的进程ID;2. 进程的执行:在子进程中通过exec()函数执行另一个可执行文件,观察进程的切换;3. 进程的退出:通过exit()函数退出进程,并观察父进程和子进程的退出代码;4. 进程间的同步与互斥:通过使用信号量机制实现进程的同步与互斥。

实验步骤与结果:1. 进程的创建:在程序中调用fork()函数创建子进程,并使用getpid()函数获取父进程和子进程的进程ID,分别输出结果。

实验结果如下:父进程的进程ID为:1234子进程的进程ID为:56782. 进程的执行:在子进程中调用exec()函数执行另一个可执行文件。

实验结果如下:父进程中输出的进程ID为:1234子进程中输出的进程ID为:78783. 进程的退出:在子进程的代码中调用exit()函数退出进程,并在父进程中通过wait()函数等待子进程的退出。

实验结果如下:子进程的退出代码为:0父进程中等待到子进程退出父进程的退出代码为:04. 进程间的同步与互斥:在程序中使用信号量机制实现进程的同步和互斥,父进程和子进程分别对共享资源进行操作。

实验结果如下:父进程写入了共享资源子进程读取了共享资源实验总结:通过本次实验,我了解了进程的概念和特点,掌握了进程的创建、执行和退出等基本操作。

同时,我还学会了使用信号量机制实现进程的同步与互斥。

通过实验可以看出,父进程和子进程是同时执行的,但是由于进程的切换,它们的执行顺序可能不确定。

此外,在进程间进行同步和互斥操作时,信号量机制可以保证共享资源的正确访问。

实验结果与预期相符,实验目的顺利达到。

实验中遇到的问题及解决方法:在实验过程中,遇到了进程执行exec()函数时进程ID的变化问题。

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

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

操作系统实验之进程管理实验报告一、实验目的本次操作系统实验的主要目的是深入理解进程管理的概念和原理,通过实际操作和观察,掌握进程的创建、调度、同步与互斥等关键机制。

二、实验环境本次实验使用的操作系统为 Windows 10,开发工具为 Visual Studio 2019,编程语言为 C++。

三、实验内容1、进程创建使用系统提供的 API 函数创建新的进程。

观察新进程的资源使用情况和运行状态。

2、进程调度编写程序模拟不同的进程调度算法,如先来先服务(FCFS)、短作业优先(SJF)和时间片轮转(RR)。

比较不同调度算法下的平均周转时间、平均等待时间等性能指标。

3、进程同步与互斥利用信号量、互斥锁等机制实现进程之间的同步与互斥。

设计并发程序,解决生产者消费者问题、读写者问题等经典同步问题。

四、实验步骤1、进程创建实验首先,包含所需的头文件,如`<windowsh>`。

然后,定义创建进程的函数,使用`CreateProcess` 函数创建新进程,并获取进程的相关信息,如进程标识符、线程标识符等。

最后,通过查看任务管理器或其他系统工具,观察新创建进程的资源占用情况。

2、进程调度实验设计不同的调度算法函数,如`FCFSSchedule`、`SJFSchedule` 和`RRSchedule`。

在每个调度算法函数中,模拟进程的到达时间、服务时间等参数,并按照相应的算法进行进程调度。

计算每个进程的周转时间和等待时间,并求出平均周转时间和平均等待时间。

3、进程同步与互斥实验定义信号量或互斥锁变量。

在生产者消费者问题中,生产者在生产产品时获取互斥锁,生产完成后释放互斥锁并通知消费者;消费者在消费产品时获取互斥锁,消费完成后释放互斥锁。

在读写者问题中,读者在读取数据时获取共享锁,读完后释放共享锁;写者在写入数据时获取独占锁,写入完成后释放独占锁。

五、实验结果与分析1、进程创建实验结果成功创建新的进程,并能够获取到进程的相关信息。

操作系统 实验一 进程管理

操作系统 实验一 进程管理
{
perror("fopen");
exit(1);
}
fputs(argv[1],fp);//向管道文件中写入输入信息
fclose(fp);//关闭文件
4、实验步骤可写编译的命令以及结果的查看命令操作等。
1、进程创建
程序:#include<stdio.h>
main()
{
int p1,p2;
while((p1=fork())==-1);
if(p1==0)
putchar('b');
else
{
while((p2=fork())==-1);
if(p2==0)
putchar('c');
else
putchar('a');
}
printf("\n");
}
2、进程互斥(应用加锁实现)
程序:#include<stdio.h>
#include<unistd.h>
main()
{
int p1,p2,i;
while ((p1=fork())==-1);
if(p1==0){
//文件管道法服务端fifoserver.c
//运行环境Redhad9.0 gcc 4.0
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#define filename "myfifo"

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

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

实验一进程管理一、目的进程调度是处理机管理的核心内容..本实验要求编写和调试一个简单的进程调度程序..通过本实验加深理解有关进程控制块、进程队列的概念;并体会和了解进程调度算法的具体实施办法..二、实验内容及要求1、设计进程控制块PCB的结构PCB结构通常包括以下信息:进程名进程ID、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等..可根据实验的不同;PCB结构的内容可以作适当的增删..为了便于处理;程序中的某进程运行时间以时间片为单位计算..各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定..2、系统资源r1…r w;共有w类;每类数目为r1…r w..随机产生n进程P i id;s j;k;t;0<=i<=n;0<=j<=m;0<=k<=dt为总运行时间;在运行过程中;会随机申请新的资源..3、每个进程可有三个状态即就绪状态W、运行状态R、等待或阻塞状态B;并假设初始状态为就绪状态..建立进程就绪队列..4、编制进程调度算法:时间片轮转调度算法本程序用该算法对n个进程进行调度;进程每执行一次;CPU时间片数加1;进程还需要的时间片数减1..在调度算法中;采用固定时间片即:每执行一次进程;该进程的执行时间片数为已执行了1个单位;这时;CPU时间片数加1;进程还需要的时间片数减1;并排列到就绪队列的尾上..三、实验环境操作系统环境:Windows系统..编程语言:C..四、实验思路和设计1、程序流程图2、主要程序代码//PCB结构体struct pcb{public int id; //进程IDpublic int ra; //所需资源A的数量public int rb; //所需资源B的数量public int rc; //所需资源C的数量public int ntime; //所需的时间片个数public int rtime; //已经运行的时间片个数public char state; //进程状态;W等待、R运行、B阻塞//public int next;}ArrayList hready = new ArrayList;ArrayList hblock = new ArrayList;Random random = new Random;//ArrayList p = new ArrayList;int m; n; r; a;a1; b;b1; c;c1; h = 0; i = 1; time1Inteval;//m为要模拟的进程个数;n为初始化进程个数//r为可随机产生的进程数r=m-n//a;b;c分别为A;B;C三类资源的总量//i为进城计数;i=1…n//h为运行的时间片次数;time1Inteval为时间片大小毫秒//对进程进行初始化;建立就绪数组、阻塞数组..public void input//对进程进行初始化;建立就绪队列、阻塞队列{m = int.ParsetextBox4.Text;n = int.ParsetextBox5.Text;a = int.ParsetextBox6.Text;b = int.ParsetextBox7.Text;c = int.ParsetextBox8.Text;a1 = a;b1 = b;c1 = c;r = m - n;time1Inteval = int.ParsetextBox9.Text;timer1.Interval = time1Inteval;for i = 1; i <= n; i++{pcb jincheng = new pcb;jincheng.id = i;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';hready.Addjincheng;//加入就绪队列}else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列}listBox1.Items.Add"当前进程状态:" + jincheng.state;}}//从数组起始地址开始输出该数组的内容public void dispArrayList list{ArrayList list1 = new ArrayList;list1 = list;if list1.Count > 0{for int j = 0; j < list1.Count; j++{pcb p = pcblist1j;listBox1.Items.Add" " + p.id.ToString + " " + p.state.ToString + " " + p.ra.ToString + " " + p.rb.ToString + " " + p.rc.ToString+" " + p.ntime.ToString + " " + p.rtime.ToString + " \r\n";}}else{listBox1.Items.Add"\r\n\t 该队列中没有进程\r\n";}}//输出就绪数组和阻塞数组的信息public void outputall{listBox1.Items.Add"当前就绪队列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片";disphready;listBox1.Items.Add"当前就阻塞列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源所需时间片已运行时间片";disphblock;}//运行就绪数组的头进程;运行一个时间片;轮转一个时间片;时间片轮转调度算法public void running{ArrayList hready1 = new ArrayList;hready1 = hready;pcb p1 = new pcb;p1=pcbhready10;p1.state='R';p1.rtime= p1.rtime + 1;h=h+1;listBox1.Items.Add"\r\n~~~~~~~当前正在运行进程ID是:" +p1.id + "~~~~~~~~\r\n";listBox1.Items.Add"\r\n进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片\r\n";listBox1.Items.Addp1.id + " " +p1.state+ " " + p1.ra + " " + p1.rb + " " + p1.rc + " " + p1.ntime + " " + p1.rtime;if p1.ntime==p1.rtime{listBox1.Items.Addp1.id.ToString+"的进程已经完成\r\n";a = a + p1.ra;b = b + p1.rb;c = c + p1.rc;hready.RemoveAt0;}else{p1.state='W';hready1.Addp1;hready.RemoveAt0;}}//检测当前资源数目是否满足阻塞数组里进程的需求public void testblock{ArrayList hblock1 = new ArrayList;hblock1 = hblock;for int m = 0; m < hblock1.Count; m++{p1 = pcbhblock1m;if a - p1.ra >= 0 && b - p1.rb >= 0 && c - p1.rc >= 0{p1.state='W';hready.Addp1;a = a - p1.ra;b = b - p1.rb;c = c - p1.rc;listBox1.Items.Add"ID号为:"+p1.id + "的进程由阻塞队列转入就绪队列~~\r\n";hblock.RemoveAtm;m--;}}}//检测是否有新的进程产生;随机产生新进程public void testnew{int t;if r>0//r为随机产生的进程数目{t = random.Next9 + 1;if t <= 7{listBox1.Items.Add"\r\n有新的进程申请加入:~~";pcb jincheng = new pcb;jincheng.id = i++;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;jincheng.rtime = 0;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';listBox1.Items.Add"进程状态为:" + jincheng.state;hready.Addjincheng;//加入就绪队列listBox1.Items.Add"资源满足新进程请求;该进程进入就绪队列~~\r\n";else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列listBox1.Items.Add"进程状态为:" + jincheng.state;listBox1.Items.Add"资源不满足新进程请求;该进程进入阻塞队列~~\r\n";}}}r = r - 1;}//系统三类资源变化情况的显示public void rescore//系统三类资源变化情况的显示{if a > a1 { textBox1.Text = a1.ToString; }if a < 0 { textBox1.Text = "0"; }if a >= 0 && a < a1 { textBox1.Text = a.ToString; }if b > b1 { textBox2.Text = b1.ToString; }if b < 0 { textBox2.Text = "0"; }if b >= 0 && b <= b1 { textBox2.Text = b.ToString; }if c > c1 { textBox3.Text = c1.ToString; }if c < 0 { textBox3.Text = "0"; }if c >= 0 && c <= c1 { textBox3.Text = c.ToString; }}//时间片轮转调度算法先来先服务FCFS算法public void runFcfs{if hready.Count>0{outputall;running;testblock;testnew;rescore;}else{timer1.Enabled = false;textBox1.Text = a1.ToString;textBox2.Text = b1.ToString;textBox3.Text = c1.ToString;listBox1.Items.Add"\r\n<<<<<<<<所有进程都已经运行结束>>>>>>>~\r\n";}//计时器触发时间片轮转调度算法private void timer1_Tickobject sender; EventArgs erunFcfs;}//开始模拟按钮单击执行函数private void button1_Clickobject sender; EventArgs e {runmain;button1.Enabled = false;textBox1.Enabled = false;textBox2.Enabled = false;textBox3.Enabled = false;textBox4.Enabled = false;textBox5.Enabled = false;textBox6.Enabled = false;textBox7.Enabled = false;textBox8.Enabled = false;textBox9.Enabled = false;}//清除屏幕按钮单击执行函数private void button2_Clickobject sender; EventArgs e {textBox1.Text = "";textBox2.Text = "";textBox3.Text = "";textBox4.Text = "";textBox5.Text = "";textBox6.Text = "";textBox7.Text = "";textBox8.Text = "";textBox9.Text = "";listBox1.Items.Clear;textBox4.Enabled = true;textBox5.Enabled = true;textBox6.Enabled = true;textBox7.Enabled = true;textBox8.Enabled = true;textBox9.Enabled = true;button1.Enabled = true;}//运行的主函数public void runmain{input;imer1.Enabled = true;3、运行界面和运行结果界面中;可以任意设定需要模拟的进程总数如5;初始化进程个数如3;还有A、B、C三类资源的总数如10、10、10..为了方便显示;还可以设定时间片的长度如500毫秒..除此之外;在运行过程中;所有的资源都是随机生成的;并且其中新进程的产生也是随机的;但是产生的进程总数不会多于开始设定的模拟的进程总数;以防止不断产生新进程;程序不断运行..在显示窗口的上方;还会实时显示资源的变化情况;方便对运行的观察..当运行结束后;可以通过工具栏中的显示选项中的保存结果按钮;将结果保存成txt文件格式;方便运行后的结果分析..五、心得体会本次实验;我的任务是设计一个允许n个进程并发运行的进程管理模拟系统..该系统包括有简单的进程控制、同步与通讯机构;系统在运行过程中能显示各进程的状态及有关参数的变化情况;从而观察诸进程的运行过程及系统的管理过程;我是用C写的;在我的电脑能够运行通过;虽不能尽善尽美;但也基本能实现老师的要求..两个星期的实验;虽然时间有点短;但我也收获不少;这次实验;加深了我对进程概念及进程管理的理解;比较熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施..也让我认识到自己的不足;操作系统的有些知识;我知道的还不多;没有掌握好;还需要多多学学;不断提升自己的能力..实验中;我们小组分工合作;共同学习;虽然在实验中遇到了一些问题;但在老师和同学的细心指导和热心帮助下解决了..同时;了解到团队精神的重要性;也为以后的学习和工作打下了坚实的基础;同时积累了宝贵的经验..。

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

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

操作系统实验课程报告课题: 进程管理实验姓名张涛学院计算机学院班级2011211311学号20112114192013年11月10日1.实验目的:(1)加深对进程概念的理解,明确进程和程序的区别;(2)进一步认识并发执行的实质;(3)分析进程争用资源的现象,学习解决进程互斥的方法;(4)了解Linux系统中进程通信的基本原理。

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

这个文件长达2616行,这里截取第1221~1548行抄录在实验报告最后,即结构体task_struct,地位相当于PCB。

下面对几个比较重要的参数,结合本人的了解以及网上查阅的资料做一点解释。

中括号内的数字为代码行号,下同。

volatile long state:【1222】进程状态字,表示进程当前的状态(运行、就绪、等待、僵死、暂停、交换),分别对应已定义好的常量;TASK_RUNING:正在运行或可运行状态;TASK_INTERRUPTIBLE:可打断睡眠状态;TASK_UNINTERRUPTIBLE:不可打断睡眠状态;TASK_ZOMBLE:僵死状态;TASK_STOPPED:暂停状态;交换状态。

void *stack:【1223】进程所使用的栈空间;unsigned int flags:【1225】进程标志(创建、关闭、跟踪、被跟踪、内核dump等),同样对应已定义好的常量;unsigned int rt_priority:【1237】表示本进程的实时优先级;const struct sched_class *sched_class、struct sched_entity se:【1239,1240】分别是调度类和调度实体,这两个结构包含了用于任务调度的完整的信息(进程信息、调度策略等);unsigned int policy:【1260】进程的调度策略标志,有三种调度标志:SCHED_OTHER :普通进程的调度策略,基于优先权的轮转法;SCHED_FIFO:实时进程的调度策略,基于先进先出的算法;SCHED_RR:实时进程的调度策略,基于优先权的轮询法。

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

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

一、实验目的本实验要求学生编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁的发生。

二、实验题目第一题:用银行家算法实现资源分配。

要求:(1) 设计一个3个并发进程共享10个同类资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。

(2)设计用银行家算法和随机分配算法,实现资源分配的两个资源分配程序,应具有显示或打印各进程依次要求申请的资源数以及依次分配资源的情况。

(3)确定一组各进程依次申请资源数的序列,在相同的情况下分别运行上述两种资源分配程序,观察运行结果。

第二题:用按序分配策略实现资源分配。

要求:(1)设计一个3个进程共享10个资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。

(2)设计用按序分配算法实现资源分配的资源分配程序,应具有显示或打印各进程依次要求申请的资源号以及依次分配资源地情况。

(3)确定两组各进程依次要求申请的资源号,要求其中的一组中各进程按序地申请资源,另一组中各进程申请资源不受序号限制,分别运行上述设计的资源分配程序,观察运行结果。

三、数据结构1)可利用资源向量available具有m个元素的数组,available[j]=k表示系统中第j类资源有k个可用2)最大需求矩阵maxn*m矩阵,max[i,j]=k表示进程i需要第j类资源的最大数目为k3)分配矩阵allocationn*m矩阵,allocation[i,j]=k表示进程i当前已占用的第j类资源的数目为k4)需求矩阵needn*m矩阵,need[i,j]=k表示进程还需要的第j类资源的数目为kneed[i,j] = max[i,j] - allocation[i,j]5)进程pi的请求向量request[i]具有m个元素的数组,说明进程pi对每类资源的请求数目6)工作向量work 系统提供给进程继续运行所需各类资源数目初值:work:=available7)状态标志finish具有n个元素的数据,表示进程是否可在有限时间内获得所有资源执行完,初值为fals#include 〈stdio.h〉#include <stdlib.h>/*————-——----—-------———常量定义-—-—————----—----—--*/#define F 0#define T 1#define n 5 //进程数量#define m 3 //资源种类数量/*——-————-—-——-——--—-—-———--—-—-——---—--———-——-----—*//*—--————----—---—--——数据结构定义-————--————--————-*/。

进程管理实验报告

进程管理实验报告

进程管理实验报告一、引言进程管理是操作系统中的重要概念之一,它负责分配和调度计算机资源,确保多个程序能够同时运行,并通过合理的资源管理提高系统的效率和性能。

本实验旨在对进程管理进行深入研究和实践,通过编写相关代码并进行测试,探索进程管理的原理和实现方式。

二、实验背景在一个多道程序设计的环境中,操作系统需要管理系统中的各个进程,分配对应的资源,并处理进程之间的竞争条件。

进程管理的核心任务包括进程的创建、运行、阻塞、唤醒和终止等操作,以及资源的调度和分配。

三、实验目标本实验旨在通过编写一个简单的进程管理程序,实现进程的创建和调度,演示进程间的合作与竞争情况,以及资源的请求和释放。

具体目标包括:1.实现进程的创建和调度算法;2.模拟进程之间的竞争条件,如互斥、死锁等;3.模拟进程的请求和释放资源的过程;4.评估不同调度算法对系统性能的影响。

四、实验设计和方法1.进程创建和调度根据操作系统的调度算法,我们可以设计一个简单的进程调度器。

首先,需要定义进程的数据结构,包括进程ID、状态、优先级等信息。

其次,实现进程的创建函数,根据用户输入的参数来创建新的进程,并将其添加到进程队列中。

最后,根据调度算法,选择一个进程进行执行,并更新进程的状态。

2.进程间的竞争条件为了模拟进程间的竞争条件,我们可以使用互斥锁和信号量等同步机制。

通过在进程中设置临界区,限定同时只有一个进程可以访问临界资源,从而避免竞争和冲突。

另外,还可以模拟不同进程之间的死锁情况,观察系统的行为和响应。

3.进程的资源请求和释放在进程管理过程中,进程需要向系统申请资源,如内存、磁盘等。

为了模拟这一过程,我们可以设计一个简单的资源管理器,并在进程中调用相应的函数来请求和释放资源。

同时,可以设置资源的使用限制和优先级,观察不同策略对系统的影响。

4.评估系统性能为了比较不同调度算法对系统性能的影响,我们可以通过测量系统的响应时间、资源利用率和吞吐量等指标来评估。

北邮大三上-操作系统-进程同步实验报告

北邮大三上-操作系统-进程同步实验报告

操作系统实验二进程同步实验班级:2009211311 学号:姓名:schnee目录1. 实验目的 (2)2. 实验要求 (2)3. 环境说明 (2)4. 实验前期思考 (2)5. 实验知识点储备 (3)5.1.进程 (3)5.2.线程 (3)5.3.同步和互斥 (3)5.4.库函数和类型储备 (4)6. 编程实现: (6)6.1. 调整和框架 (6)6.2. 源程序实现(详细框架见注释) (6)6.3. 实现中遇到过的困难和解决方法 (9)6.4. 运行示例及结果截图 (10)7. 心得和优化 (11)1.实验目的1)理解进程/线程同步的方法,学会运用进程/线程同步的方法解决实际问题;2)了解windows系统或unix/linux系统下中信号量的使用方法。

2.实验要求编写一个有关生产者和消费者的程序:每个生产者每次生产一个产品存入仓库,每个消费者每次从仓库中取出一个产品进行消费,仓库大小有限,每次只能有一个生产者或消费者访问仓库。

要求:采用信号量机制。

3.环境说明此实验采用的是Win7下Code::blocks 10.05编译器,采用Win API的信号量机制编程。

此word实验文档中采用notepad++的语法高亮。

4.实验前期思考可能有多个生产者和消费者。

可以假设输入P表示创建一个生产者线程,输入C表示创建一个消费者线程。

生产者线程等待仓库有空位并且占据此空位,,然后等待仓库的操作权,执行操作,最后释放仓库操作权。

一开始以为是占位的操作在获得操作权后,疑惑:若是等待空位后在等待获得操作权时又没有空位了,岂不是又不能放入了?若是先获得操作权再等空位,则在无空位时会进入无穷等待状态,因为没有人来改变空位个数。

这两个问题如何克服呢?其实第一个疑问是因为我对wait函数的具体操作还有点模糊,实际上wait操作便是一等到空位就顺便占了,而不是我想的等位和占位分离。

而第二个问题自然是不行的,这种操作顺序应该抛弃。

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

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

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

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

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

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

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

源代码如下:#include<sys/types.h>#include<stdio.h>#include<unistd.h>#include <fcntl.h>#include <errno.h>int main(int argc,char* argv[]){pid_t pid1,pid2;pid1 = fork();if(pid1<0){fprintf(stderr,"childprocess1 failed");exit(-1);}1/12else 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();操作系统创建一个新的进程(子进程),并且在进程表中相应为它建2/12立一个新的表项。

新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!因此,这三个进程哪个先执行,哪个后执行,完全取决于操作系统的调度,没有固定的顺序。

(2)进程的控制修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。

将父进程的输出改为father process completed输出b的子进程改为输出child process1 completed输出c的子进程改为输出child process2 completed运行的结果如下:理由同(1)如果在程序中使用系统调用lockf () 来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。

加锁之后的代码:#include<sys/types.h>#include<stdio.h>#include<unistd.h>#include <fcntl.h>#include <errno.h>int main(int argc,char* argv[]){pid_t pid1,pid2;pid1 = fork();if(pid1<0){fprintf(stderr,"childprocess1 failed");exit(-1);3/12}else if(pid1 == 0){lockf(1,1,0);printf("child process1 completed\n");}else{pid2 = fork();if(pid2<0){fprintf(stderr,"childprocess1 failed");exit(-1);}else if(pid2 == 0){lockf(1,1,0);printf("child process2 completed\n");}else{lockf(1,1,0);printf(“father process is completed\n”);sleep(2);exit(0);}}return 0;}4/12所谓进程互斥,是指两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥.lockf()函数是将文件区域用作信号量(监视锁),或控制对锁定进程的访问(强制模式记录锁定)。

试图访问已锁定资源的其他进程将返回错误或进入休态,直到资源解除锁定为止。

而上面三个进程,不存在要同时进入同一组共享变量的临界区域的现象,因此输出和原来相同。

(3)a) 编写一段程序,使其实现进程的软中断通信。

要求:使用系统调用fork() 创建两个子进程,再用系统调用signal() 让父进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill() 向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child Process 1 is killed by Parent!Child Process 2 is killed by Parent!父进程等待两个子进程终止后,输出如下的信息后终止:Parent Process is killed!代码如下:#include<sys/types.h>#include<stdio.h>#include<unistd.h>#include <fcntl.h>#include <errno.h>#include <signal.h>int wf;void waiting(){while(wf!=0);}5/12void stop(){wf = 0;}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){wf = 1;signal(16,stop);//捕捉到父进程传来的16信号,继续往下执行waiting();//不往下执行lockf(1,1,0);printf("Child Process 1 is killed by Parent!\n");lockf(1,0,0);exit(0);}else{6/12pid2 = fork();if(pid2<0){fprintf(stderr,"childprocess1 failed");exit(-1);}else if(pid2 == 0){wf = 1;signal(17,stop);//捕捉到父进程传来的17信号,继续往下执行waiting();//不往下执行lockf(1,1,0);printf("Child Process 2 is killed by Parent!\n");lockf(1,0,0);exit(0);}else{wf = 1;//wf为1时,不往下执行,直到捕捉到键盘上传来的信号signal(SIGINT,stop);//捕捉到键盘传来的信号,执行stop函数waiting();kill(pid1,16);//向子进程p1发软中断信号16kill(pid2,17);//向子进程p2发软中断信号17wait(0);7/12wait(0);printf("Parent Process is killed!\n");exit(0);}}return 0;按下ctrl+c后,运行结果如下:软中断一般是指由指令int引起的“伪”中断动作——给CPU制造一个中断的假象;而硬中断则是实实在在由8259的连线触发的中断。

kill函数的原型如下:int kill(pid,sig),pid 是一个或一组进程的标识符,参数sig是要发送的软中断信号。

signal函数的原型如下:signal(sig,function),它以软中断信号的序号作为参数调用函数,也就是说,收到软中断信号sig后,调用函数function.当子进程1收到软中断信号16时,调用函数stop()解除“waiting”,继续往下执行;等它打印完了child process 1 is killed by parent,就退出;对于子进程2来说也是如此。

而父进程在此阶段一直处于“waiting”状态(执行wait(0)),直到两个子进程都退出了,父进程才会退出。

由于ctrl+c信号会并发传到每个进程中,进程受到该信号会立刻终止。

当子进程收到ctrl+c信号时,就终止了,根本不会等父进程传来的软中断信号,因此也就不会打印出child process1 is killed和child process2 is killed.b) 在上面的程序中增加语句signal(SIGINT, SIG-IGN) 和signal(SIGQUIT, SIG-IGN),观察执行结果,并分析原因。

按下ctrl+c后,运行结果如下:signal(SIGINT, SIG-IGN)和signal(SIGQUIT, SIG-IGN)的作用是屏蔽从键盘上传来的中断信号,因此子进程可以接收到父进程传来的软中断信号,进而将那两句话打印出来8/12(4)进程的管道通信编制一段程序,实现进程的管道通信。

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

要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。

源代码如下:#include<sys/types.h>#include<stdio.h>#include<unistd.h>#include <fcntl.h>#include <errno.h>int main(int argc,char* argv[]){pid_t pid1,pid2;int fd[2];char parbuf[50],childbuf[50];pipe(fd);//建立管道pid1 = fork();if(pid1<0){fprintf(stderr,"childprocess2 failed");exit(-1);}else if(pid1 == 0){lockf(fd[1],1,0);sprintf(childbuf,"Child 2 is sending a message!\n");write(fd[1],childbuf,50);//向管道中写东西sleep(5);9/12lockf(fd[1],0,0);exit(0);}else{pid2 = fork();if(pid2<0){fprintf(stderr,"childprocess1 failed");exit(-1);}else if(pid2 == 0){lockf(fd[1],1,0);sprintf(childbuf,"Child 1 is sending a message!\n");write(fd[1],childbuf,50);//向管道中写东西sleep(5);lockf(fd[1],0,0);exit(0);}else{wait(0);//等待某个子进程结束read(fd[0],parbuf,50);//从管道中读东西printf("%s",parbuf);wait(0);//等待某个子进程结束read(fd[0],parbuf,50);//从管道中读东西printf("%s",parbuf);exit(0);}}return 0;10/12}运行结果如下:值得注意的是,pipe(fd);pid1 = fork();这两句的位置不能调换,否则会出现下面结果:也就是说,只有子进程1向通过管道向父进程发送信息,且程序一直不退出。

相关文档
最新文档