实验二进程同步实验报告

合集下载

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

操作系统实验实验报告

操作系统实验实验报告

操作系统实验实验报告一、实验目的操作系统是计算机系统中最为关键的核心软件,它管理着计算机的硬件资源和软件资源,为用户提供了一个方便、高效、稳定的工作环境。

本次操作系统实验的目的在于通过实际操作和实践,深入理解操作系统的基本原理和核心概念,掌握操作系统的基本功能和操作方法,提高对操作系统的认识和应用能力。

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

实验硬件环境为一台配备Intel Core i7 处理器、16GB 内存、512GB SSD 硬盘的个人计算机。

三、实验内容(一)进程管理实验1、进程创建与终止通过编程实现创建新的进程,并在完成任务后终止进程。

在实验中,我们使用了 Windows API 函数 CreateProcess 和 TerminateProcess 来完成进程的创建和终止操作。

通过观察进程的创建和终止过程,深入理解了进程的生命周期和状态转换。

2、进程同步与互斥为了实现进程之间的同步与互斥,我们使用了信号量、互斥量等同步对象。

通过编写多线程程序,模拟了多个进程对共享资源的访问,实现了对共享资源的互斥访问和同步操作。

在实验中,我们深刻体会到了进程同步与互斥的重要性,以及不正确的同步操作可能导致的死锁等问题。

(二)内存管理实验1、内存分配与释放使用 Windows API 函数 VirtualAlloc 和 VirtualFree 进行内存的分配和释放操作。

通过实验,了解了内存分配的不同方式(如堆分配、栈分配等)以及内存释放的时机和方法,掌握了内存管理的基本原理和操作技巧。

2、内存分页与分段通过编程模拟内存的分页和分段管理机制,了解了内存分页和分段的基本原理和实现方法。

在实验中,我们实现了简单的内存分页和分段算法,对内存的地址转换和页面置换等过程有了更深入的理解。

(三)文件系统实验1、文件操作使用 Windows API 函数 CreateFile、ReadFile、WriteFile 等进行文件的创建、读取和写入操作。

操作系统实验二实验报告

操作系统实验二实验报告

操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。

通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。

二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。

三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。

2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。

3、为新进程指定可执行文件的路径、命令行参数、进程属性等。

4、编写代码来等待新进程的结束,并获取其退出代码。

(二)进程同步实验1、设计一个生产者消费者问题的模型。

2、使用信号量来实现生产者和消费者进程之间的同步。

3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。

4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。

(三)进程通信实验1、选择使用管道来实现进程之间的通信。

2、创建一个匿名管道,父进程和子进程分别读写管道的两端。

3、父进程向管道写入数据,子进程从管道读取数据并进行处理。

四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。

通过观察进程的创建和执行过程,加深了对进程概念的理解。

(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。

分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。

(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。

数据能够准确地在进程之间传递,验证了管道通信的有效性。

五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。

通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。

(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。

进程的同步与互斥实验报告

进程的同步与互斥实验报告

进程的同步与互斥实验报告1.实验目的进程(线程)的同步与互斥是操作系统中非常重要的概念,本实验旨在通过实际操作,加深对这些概念的理解和掌握。

通过编写多个进程(线程),并在其间进行同步与互斥操作,验证同步与互斥的实际效果。

2.实验环境本实验在Linux系统下进行,使用C/C++语言编程。

3.实验内容3.1同步在实验中,我们编写了两个进程A和B,这两个进程需要按照特定的顺序执行。

为了实现同步,我们使用信号量机制来确保进程A和B按照正确的顺序执行。

3.2互斥在实验中,我们编写了多个进程C和D,这些进程需要同时对一个共享资源进行访问。

为了实现互斥,我们使用互斥锁机制来确保同一时刻只有一个进程访问共享资源。

4.实验过程4.1同步实验编写进程A和进程B的代码,使用信号量机制实现同步。

进程A先运行,然后通过信号量唤醒进程B,进程B再开始执行。

通过观察进程的运行顺序,验证同步机制是否起作用。

4.2互斥实验编写进程C和进程D的代码,使用互斥锁机制实现互斥。

进程C和进程D同时对一个共享资源进行访问,通过互斥锁来确保同一时刻只有一个进程访问共享资源。

观察进程的输出结果,验证互斥机制是否起作用。

5.实验结果5.1同步实验结果进程A开始执行进程A执行完毕进程B开始执行进程B执行完毕5.2互斥实验结果进程C开始执行进程C访问共享资源进程C执行完毕进程D开始执行进程D访问共享资源进程D执行完毕6.实验分析通过上述结果可以看出,同步实验中进程A和进程B按照正确的顺序执行,证明了同步机制的有效性。

互斥实验中进程C和进程D能够正确地交替访问共享资源,证明了互斥机制的有效性。

7.实验总结通过本次实验,我深刻理解了进程(线程)的同步与互斥,并通过实际操作加深了对这些概念的理解。

同步和互斥是操作系统中非常重要的概念,对于应对资源竞争和提高程序性能具有重要意义。

在实际开发中,我们应该合理使用同步和互斥机制,以确保程序的正确性和并发执行的效率。

进程同步:实验报告

进程同步:实验报告

进程同步:实验报告1.实验内容(进程的同步)(1) 阅读理解⽰例程序。

(2) 说明⽰例程序是否能适合解决 N 个⽣产者和 1 个消费者问题,并设计实验验证(3) 参照教材修改为 N 个⽣产者和 1 个消费者问题(4) 思考 N 个⽣产者和 M 个消费者问题的解决⽅案(不要求)(5) 利⽤信号量解决同步问题。

2.实验⽬的通过程序模拟及验证⽣产者消费者问题等经典问题,深⼊理解并发中的同步和互斥的概念3.实验原理(1)进程概念:(1.定义:程序的⼀次执⾏过程( 2.三种基本状态 :就绪状态,执⾏状态,阻塞状态(2)进程同步:(1.定义:并发进程在执⾏次序上的协调,以达到有效的资源共享和相互合作,使程序执⾏有可再现性。

( 2.两种形式的制约关系: (⼀:资源共享关系:进程间接制约,需互斥地访问临界资源。

)、(⼆:相互合作关系:进程直接制约)(3.临界资源:⼀次仅允许⼀个进程访问的资源,引起不可再现性是因为临界资源没有互斥访问。

(3)信号量:定义⼀个⽤于表⽰资源数⽬的整型量S,它与⼀般的整型量不同,除初始化外,仅能通过两个标准的原⼦操作 wait(S)和 signal(S)来访问,俗称 P,V操作。

通俗来讲就是⽤P 来访问资源后减去⼀个单位资源,⽤ V 操作来释放⼀个单位资源就是现有资源上加⼀个单位资源。

4.实验内容⼀:说明⽰例程序是否能适合解决 N 个⽣产者和 1 个消费者问题,并设计实验验证答:⽰例程序不能解决多个⽣产者和消费者的问题,它是解决单个消费者和⽣产者的。

如果可以就要修改代码,如“⼆”所说。

⼆:多个消费者和⽣产者的问题⽣产者 1 如上图所⽰:如果要解决多个⽣产者和消费者的问题:第⼀步:分析上图得出了两种关系,分别是异步和同步的关系第⼆步:异步关系的是⽣产者和⽣产者之间的,因为同⼀时刻只能有⼀个⽣产者访问缓冲区,所以我们就可以设置临界资源 .获得临界资源的⽣产者才能把产品放到缓冲区⾥第三步:同步关系有两个,⾸先是⽣产者和缓冲区之间,再是缓冲区和消费者之间。

进程同步实验报告

进程同步实验报告

一、实验目的1. 理解进程同步的概念和原理;2. 掌握进程同步的基本方法和机制;3. 学会使用信号量实现进程同步;4. 通过实验验证进程同步机制的有效性。

二、实验原理1. 进程同步:在多道程序设计中,进程的执行是并发的,但某些情况下需要保证多个进程按照一定的顺序执行,以避免出现数据不一致、死锁等问题。

进程同步是指通过某种机制,协调多个进程的执行顺序,保证它们能够正确、有效地共享资源。

2. 信号量:信号量是一种特殊的变量,用于实现进程同步。

信号量具有两个原子操作:P操作(wait)和V操作(signal)。

P操作用于申请资源,V操作用于释放资源。

3. 互斥锁:互斥锁是一种常见的进程同步机制,用于保证临界资源的互斥访问。

当一个进程进入临界区时,它会尝试获取互斥锁,如果锁已被其他进程获取,则该进程进入等待状态;当进程退出临界区时,它会释放互斥锁。

三、实验内容1. 实验环境:Linux操作系统,C语言编程环境。

2. 实验工具:gcc编译器、gdb调试器。

3. 实验步骤:(1)创建一个互斥锁,用于保护临界资源。

(2)编写两个进程,分别模拟对临界资源的访问。

(3)在进程访问临界资源前,使用P操作尝试获取互斥锁。

(4)在进程访问临界资源后,使用V操作释放互斥锁。

(5)编译并运行程序,观察进程执行情况。

四、实验结果与分析1. 实验结果:(1)在互斥锁的保护下,两个进程能够按照预期顺序访问临界资源。

(2)当其中一个进程正在访问临界资源时,另一个进程会进入等待状态。

(3)当进程访问临界资源完成后,它会释放互斥锁,允许其他进程访问。

2. 实验分析:(1)互斥锁能够有效地保护临界资源,避免数据不一致问题。

(2)信号量P操作和V操作保证了进程的同步,避免了死锁现象。

(3)通过实验验证了进程同步机制的有效性。

五、实验总结本次实验通过使用信号量和互斥锁,实现了进程同步。

实验结果表明,信号量和互斥锁能够有效地保证进程按照预期顺序执行,避免数据不一致和死锁等问题。

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

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.实验目的:1)使用EOS 的信号量,编程解决生产者—消费者问题,理解进程同步的意义;2)调试跟踪EOS 信号量的工作过程,理解进程同步的原理;3)修改EOS 的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

3.实验类型:验证+设计4.实验内容:1)准备实验2)使用EOS 的信号量解决生产者-消费者问题3)调试EOS 信号量的工作过程4)修改EOS 的信号量算法二.实验环境操作系统:windows XP编译器:Tevalaton OS Lab语言:C三.实验过程1.设计思路和流程图2.实验过程1)准备实验,启动OS Lab,新建一个EOS Kernel项目和EOS应用程序,将EOS Kernel 项目中生成的SDK文件覆盖到ROS应用程序项目文件夹中的SDK文件夹;2)使用pc.c文件中的源代码,替换之前创建的EOS应用程序项目中EOSApp.c文件中的代码,并生成项目,启动调试,忽略调试的异常,立即激活虚拟机窗口中查看生产者-消费者同步执行的过程,结束此次调试;3)信号量结构体(SEMAPHORE)中的各个成员变量是由API 函数CreateSemaphore 的对应参数初始化的。

创建信号量,启动调试EOS应用程序,在OS Lab弹出的调试异常对话框中选择“是”,进入异常调试,在main函数中创建Empty信号量的代码行添加断点;EmptySemaphoreHandle = CreateSemaphore(BUFFER_SIZE, BUFFER_SIZE, NULL);4)启动调试,逐语句调试进入CreateSemaphore 函数。

可以看到此API 函数只是调用了EOS内核中的PsCreateSemaphoreObject 函数来创建信号量对象,继续逐语句调试试进入semaphore.c 文件中的PsCreateSemaphoreObject 函数。

操作系统实验报告——进程同步与互斥

操作系统实验报告——进程同步与互斥

操作系统实验报告——进程同步与互斥一、实验内容本实验主要内容是通过编写程序来实现进程的同步与互斥。

具体来说,是通过使用信号量来实现不同进程之间的同步和互斥。

我们将编写两个进程,一个进程负责打印奇数,另一个进程负责打印偶数,两个进程交替打印,要求打印的数字从1开始,直到100结束。

二、实验原理进程的同步是指多个进程之间按照一定的顺序执行,进程之间互相等待的关系。

而进程的互斥是指多个进程竞争同一个资源,需要通过其中一种方式来避免同时访问共享资源,以免造成数据错乱。

在本实验中,我们使用信号量来实现进程的同步与互斥。

信号量是一个计数器,用于表示一些共享资源的可用数量。

进程在访问共享资源时,需要先对信号量进行操作,当信号量大于0时,表示资源可用,进程可以访问;当信号量等于0时,表示资源不可用,进程需要等待。

进程同步的实现可以通过信号量的P操作与V操作来完成。

P操作用于申请资源,当资源可用时,将计数器减一,并进入临界区;V操作用于释放资源,当资源使用完毕时,将计数器加一,使等待资源的进程能够申请。

进程互斥的实现可以通过信号量的P操作与V操作结合临界区来完成。

当多个进程需要访问共享资源时,需要先进行P操作,进入临界区,访问完毕后进行V操作,离开临界区。

三、实验步骤1.首先,我们需要创建两个进程,一个进程负责打印奇数,另一个进程负责打印偶数。

2. 然后,我们创建一个共享变量count,用来记录打印的数字。

3. 接着,我们创建两个信号量odd和even,用来控制进程的同步与互斥。

odd信号量初始值为1,表示打印奇数的进程可以访问;even信号量初始值为0,表示打印偶数的进程需要等待。

4.编写奇数打印进程的代码,首先进行P操作,判断奇数信号量是否大于0,如果大于0,表示可以打印奇数。

5. 如果可以打印奇数,将count加一,并输出当前的奇数,然后进行V操作,释放偶数打印进程的等待。

6.同样的,编写偶数打印进程的代码,首先进行P操作,判断偶数信号量是否大于0,如果大于0,表示可以打印偶数。

进程的同步实验报告

进程的同步实验报告

进程的同步实验报告进程的同步实验报告引言:进程同步是操作系统中一个重要的概念,它涉及到多个进程之间的协调和合作。

在本次实验中,我们将通过一个简单的实例来探讨进程同步的概念和实现方式。

实验目的:通过实验,我们的目标是理解进程同步的概念,学习常见的同步机制,并通过编程实现一个简单的同步问题。

实验环境:本次实验使用了C语言作为编程语言,并在Linux操作系统上进行。

实验过程:我们的实验场景是一个餐厅,有一个厨师和多个服务员。

厨师负责烹饪菜品,服务员负责上菜给客人。

我们需要实现的是,服务员只有在厨师烹饪好一道菜之后才能上菜,否则需要等待。

首先,我们使用互斥锁来实现进程间的同步。

互斥锁是一种常见的同步机制,它可以确保在同一时间只有一个进程可以访问共享资源。

在我们的实验中,厨师和服务员都需要访问菜品资源,因此我们为菜品资源添加了一个互斥锁。

接下来,我们使用条件变量来实现进程间的等待和唤醒操作。

条件变量是一种同步机制,它可以让进程在某个条件满足时等待,直到被唤醒。

在我们的实验中,服务员需要等待厨师烹饪好菜品之后才能上菜,因此我们创建了一个条件变量,并在服务员的代码中使用了等待和唤醒操作。

实验结果:经过实验,我们成功地实现了进程间的同步。

在我们的实验场景中,厨师会不断地烹饪菜品,并在烹饪完成后通知服务员上菜。

服务员会等待厨师的通知,然后上菜给客人。

通过互斥锁和条件变量的使用,我们保证了服务员只会在厨师烹饪完成后才会上菜,避免了资源竞争和错误的上菜行为。

讨论与总结:通过本次实验,我们深入理解了进程同步的概念和实现方式。

互斥锁和条件变量是常见的同步机制,它们可以有效地解决进程间的竞争和协调问题。

在实际的操作系统中,进程同步是一个非常重要的概念,它保证了多个进程之间的正确执行和合作。

然而,进程同步也可能引发一些问题。

例如,如果互斥锁的使用不当,可能会导致死锁的发生。

死锁是一种进程无法继续执行的状态,它会导致系统的停滞。

操作系统实验报告范文模板

操作系统实验报告范文模板

操作系统实验报告范文模板这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。

里面的程序都是我运行过的。

操作系统上机实验报告班级:学号:姓名:实验地点:实验时间:这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。

里面的程序都是我运行过的。

实验一进程的建立【实验目的】创建进程及子进程在父子进程间实现进程通信【实验软硬件环境】Linu某、Window98、Window2000【实验内容】创建进程并显示标识等进程控制块的属性信息;显示父子进程的通信信息和相应的应答信息。

(进程间通信机制任选)【实验程序及分析】编程思路:首先本程序在Linu某用C语言完成的,父子进程的创建用fork函数来实现,然后是父子进程间的通信,这里用pipe实现。

可以定义chan1[2],chan1[2],chan某[0]表示读,chan某[1]表示写。

他们配合使用。

【实验截图】【实验心得体会】通过这次上机练习,我熟悉了用c++实现进程的创建,销毁,父子进程间的通讯等一系列课程中需要学习的内容。

本来进程的概念在一开始我始终无法清晰地理解,但是通过自己用mfc的方法去实现它后,我开始慢慢地理解操作系统的进程的运作机制。

虽然,我只是实现了一个父子进程的创建和通讯,但是,管中窥豹,我想自己开始明白一个操作系统正是由很多这种进程实现功能的。

其中,系统整体的进程调度,管理等等还有很多东西等着我们去进一步学习、理解。

实验二进程间的同步【实验目的】这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。

里面的程序都是我运行过的。

理解进程同步和互斥模型及其应用【实验软硬件环境】Linu某、Window98、Window2000【实验内容】利用通信API实现进程之间的同步:建立司机和售票员进程;并实现他们间的同步运行。

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

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

实验一、进程管理与进程同步一、实验目的了解进程管理的实现方法,理解和掌握处理进程同步问题的方法。

二、实验内容实现银行家算法、进程调度过程的模拟、读者-写者问题的写者优先算法。

实验步骤:理解安全性算法和银行家算法的核心机制:针对3类资源、5个进程的情况,设计相应的数据结构,分别表示每个进程占用各类资源的情况;编程实现安全性算法函数,编制主函数,动态输入资源的占用情况,进程的资源申请,调用安全性函数,实现银行家算法;测试:输入可分配和不可分配的请求,测试系统的正确性。

三、实验环境Windows 2000;Microsoft Visual C++ 6.0四、程序源码与运行结果银行家算法代码:#include "malloc.h"#include "stdio.h"#include "stdlib.h"#define alloclen sizeof(struct allocation)#define maxlen sizeof(struct max)#define avalen sizeof(struct available)#define needlen sizeof(struct need)#define finilen sizeof(struct finish)#define pathlen sizeof(struct path)struct allocation{int value;struct allocation *next;};struct max{int value;struct max *next;};struct available /*可用资源数*/{int value;struct available *next;};struct need /*需求资源数*/{int value;struct need *next;};struct path{int value;struct path *next;};struct finish{int stat;struct finish *next;};int main(){int row,colum,status=0,i,j,t,temp,processtest;struct allocation *allochead,*alloc1,*alloc2,*alloctemp;struct max *maxhead,*maxium1,*maxium2,*maxtemp;struct available *avahead,*available1,*available2,*workhead,*work1,*work2,*worktemp,*worktemp1; struct need *needhead,*need1,*need2,*needtemp;struct finish *finihead,*finish1,*finish2,*finishtemp;struct path *pathhead,*path1,*path2;printf("\n请输入系统资源的种类数:");scanf("%d",&colum);printf("请输入现时内存中的进程数:");scanf("%d",&row);printf("请输入已分配资源矩阵:\n");for(i=0;i<row;i++){for (j=0;j<colum;j++){printf("请输入已分配给进程 p%d 的 %c 种系统资源:",i,'A'+j);if(status==0){allochead=alloc1=alloc2=(struct allocation*)malloc(alloclen);alloc1->next=alloc2->next=NULL;scanf("%d",&allochead->value);status++;}else{alloc2=(struct allocation *)malloc(alloclen);scanf("%d,%d",&alloc2->value);if(status==1){allochead->next=alloc2;status++;}alloc1->next=alloc2;alloc1=alloc2;}}}alloc2->next=NULL;status=0;printf("请输入最大需求矩阵:\n");for(i=0;i<row;i++){for (j=0;j<colum;j++){printf("请输入进程 p%d 种类 %c 系统资源最大需求:",i,'A'+j);if(status==0){maxhead=maxium1=maxium2=(struct max*)malloc(maxlen);maxium1->next=maxium2->next=NULL;scanf("%d",&maxium1->value);status++;}else{maxium2=(struct max *)malloc(maxlen);scanf("%d,%d",&maxium2->value);if(status==1){maxhead->next=maxium2;status++;}maxium1->next=maxium2;maxium1=maxium2;}}}maxium2->next=NULL;status=0;printf("请输入现时系统剩余的资源矩阵:\n");for (j=0;j<colum;j++){printf("种类 %c 的系统资源剩余:",'A'+j);if(status==0){avahead=available1=available2=(struct available*)malloc(avalen); workhead=work1=work2=(struct available*)malloc(avalen);available1->next=available2->next=NULL;work1->next=work2->next=NULL;scanf("%d",&available1->value);work1->value=available1->value;status++;}else{available2=(struct available*)malloc(avalen);work2=(struct available*)malloc(avalen);scanf("%d,%d",&available2->value);work2->value=available2->value;if(status==1){avahead->next=available2;workhead->next=work2;status++;}available1->next=available2;available1=available2;work1->next=work2;work1=work2;}}available2->next=NULL;work2->next=NULL;status=0;alloctemp=allochead;maxtemp=maxhead;for(i=0;i<row;i++)for (j=0;j<colum;j++){if(status==0){needhead=need1=need2=(struct need*)malloc(needlen); need1->next=need2->next=NULL;need1->value=maxtemp->value-alloctemp->value;status++;}else{need2=(struct need *)malloc(needlen);need2->value=(maxtemp->value)-(alloctemp->value); if(status==1)needhead->next=need2;status++;}need1->next=need2;need1=need2;}maxtemp=maxtemp->next;alloctemp=alloctemp->next;}need2->next=NULL;status=0;for(i=0;i<row;i++){if(status==0){finihead=finish1=finish2=(struct finish*)malloc(finilen); finish1->next=finish2->next=NULL;finish1->stat=0;status++;}else{finish2=(struct finish*)malloc(finilen);finish2->stat=0;if(status==1){finihead->next=finish2;status++;}finish1->next=finish2;finish1=finish2;}}finish2->next=NULL; /*Initialization compleated*/status=0;processtest=0;for(temp=0;temp<row;temp++){alloctemp=allochead;needtemp=needhead;finishtemp=finihead;worktemp=workhead;for(i=0;i<row;i++)worktemp1=worktemp;if(finishtemp->stat==0){for(j=0;j<colum;j++,needtemp=needtemp->next,worktemp=worktemp->next) if(needtemp->value<=worktemp->value)processtest++;if(processtest==colum){for(j=0;j<colum;j++){worktemp1->value+=alloctemp->value;worktemp1=worktemp1->next;alloctemp=alloctemp->next;}if(status==0){pathhead=path1=path2=(struct path*)malloc(pathlen);path1->next=path2->next=NULL;path1->value=i;status++;}else{path2=(struct path*)malloc(pathlen);path2->value=i;if(status==1){pathhead->next=path2;status++;}path1->next=path2;path1=path2;}finishtemp->stat=1;}else{for(t=0;t<colum;t++)alloctemp=alloctemp->next;finishtemp->stat=0;}}elsefor(t=0;t<colum;t++){needtemp=needtemp->next;alloctemp=alloctemp->next;}processtest=0;worktemp=workhead;finishtemp=finishtemp->next;}}path2->next=NULL;finishtemp=finihead;for(temp=0;temp<row;temp++){if(finishtemp->stat==0){printf("\n系统处于非安全状态!\n"); exit(0);}finishtemp=finishtemp->next;}printf("\n系统处于安全状态.\n"); printf("\n安全序列为: \n");do{printf("p%d ",pathhead->value);}while(pathhead=pathhead->next);printf("\n");return 0;}运行结果:备注:输入数据为P110 银行家算法之例所用数据《计算机操作系统》(第三版)西安电子科技大学出版社银行家算法原理说明:银行家算法是一种最有代表性的避免死锁的算法。

进程同步实验报告

进程同步实验报告
2.设计过程:
设置司机与售票员的信号量为全局变量,并客车的人数:现在人数、下车人数、上车人数为全局变量;设置司机与售票员的线程。考虑到第一站和最后一站的问题,应单独处理,故在各自的线程中分情况讨论:
具体的思路是下面的图示。
还有就是那个下车的人数是随机数,设计时考虑到了人数可能会超过客车的最大上限的问题。
2.程序的实现(代码):
#include<stdlib.h>
#include<stdio.h>
#include<windows.h
#define Total_num 60 //客车的最大容量
#define Total_pork 10 //总的站数
//全局变量
int Recent_num=0; //某一时刻的客车上的人数
Recent_num+=Get_on_num;
printf("现在总共有 %d 人在车上。\n",Recent_num);
}
else
{
printf("客车已停止,售票员可以让乘客上下车了。\n");
Get_off_num=Get_random(0,Recent_num);
printf("%d人从第 %d 站下车。\n",Get_off_num,pork);
}
Sleep(1000);
}
return 0;
}
//Conductor的线程
DWORD WINAPI Thread_Conductor(LPVOID Conductor)
{
while(1)
{
if( pork < Total_pork)
{
printf("该站是第 %d 站\n",pork);

操作系统课程实验报告

操作系统课程实验报告

操作系统课程实验报告一、实验目的操作系统是计算机系统中最为关键的软件之一,它负责管理计算机的硬件资源和软件资源,为用户提供一个良好的工作环境。

通过操作系统课程实验,旨在深入理解操作系统的基本原理和功能,提高对操作系统的实际操作能力和问题解决能力。

二、实验环境本次实验使用的操作系统为Windows 10 和Linux(Ubuntu 1804),开发工具包括 Visual Studio Code、gcc 编译器等。

三、实验内容(一)进程管理1、进程创建与终止在 Windows 系统中,使用 C++语言创建多个进程,并通过进程句柄控制进程的终止。

在 Linux 系统中,使用 fork()系统调用创建子进程,并通过 exit()函数终止进程。

2、进程同步与互斥使用信号量实现进程之间的同步与互斥。

在 Windows 中,利用CreateSemaphore()和 WaitForSingleObject()等函数进行操作;在Linux 中,通过 sem_init()、sem_wait()和 sem_post()等函数实现。

(二)内存管理1、内存分配与释放在 Windows 中,使用 HeapAlloc()和 HeapFree()函数进行动态内存的分配与释放。

在 Linux 中,使用 malloc()和 free()函数完成相同的操作。

2、内存页面置换算法实现了几种常见的内存页面置换算法,如先进先出(FIFO)算法、最近最少使用(LRU)算法等,并比较它们的性能。

(三)文件系统管理1、文件创建与读写在 Windows 和 Linux 系统中,分别使用相应的 API 和系统调用创建文件,并进行读写操作。

2、目录操作实现了目录的创建、删除、遍历等功能。

四、实验步骤(一)进程管理实验1、进程创建与终止(1)在 Windows 系统中,编写 C++程序,使用 CreateProcess()函数创建新进程,并通过 TerminateProcess()函数终止指定进程。

进程的控制_实验报告

进程的控制_实验报告

### 实验目的1. 理解操作系统进程控制的基本概念和原理。

2. 掌握进程的创建、同步、通信和终止等操作。

3. 熟悉Linux系统中的进程控制命令和系统调用。

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

### 实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 编译器:gcc4. 开发工具:vim### 实验内容本实验主要涉及以下内容:1. 进程的创建与终止2. 进程同步与通信3. 进程调度算法#### 1. 进程的创建与终止实验一:利用fork()创建进程```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); printf("Child process is running...\n");sleep(2);printf("Child process is exiting...\n");return 0;} else {printf("Parent process, PID: %d\n", getpid()); printf("Parent process is running...\n");sleep(3);printf("Parent process is exiting...\n");wait(NULL);}return 0;}```实验二:利用exec()创建进程```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {execlp("ls", "ls", "-l", (char )NULL); printf("execlp() error\n");return 1;} else {wait(NULL);}return 0;}```实验三:进程终止```c#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); sleep(2);printf("Child process is exiting...\n");exit(0);} else {wait(NULL);}return 0;}```#### 2. 进程同步与通信实验四:使用信号实现进程同步```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>int main() {pid_t pid;int status;int signalNo = 1;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); while (1) {pause();printf("Child process is running...\n"); }} else {printf("Parent process, PID: %d\n", getpid()); sleep(1);kill(pid, signalNo);wait(NULL);}return 0;}```实验五:使用管道实现进程通信```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {int pipefd[2];pid_t pid;char buffer[100];if (pipe(pipefd) == -1) {printf("pipe() error\n"); return 1;}pid = fork();if (pid < 0) {printf("fork() error\n"); return 1;} else if (pid == 0) {close(pipefd[0]);read(pipefd[1], buffer, sizeof(buffer));printf("Child process, PID: %d, Received: %s\n", getpid(), buffer);} else {close(pipefd[1]);write(pipefd[0], "Hello, Child!\n", 14);wait(NULL);}return 0;}```#### 3. 进程调度算法实验六:先来先服务(FCFS)调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```实验七:时间片轮转调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```### 实验总结通过本次实验,我对操作系统进程控制有了更深入的了解。

操作系统实验报告-进程同步与互斥

操作系统实验报告-进程同步与互斥

操作系统实验报告-进程同步与互斥(总12页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--《进程同步与互斥》实验报告学号姓名专业、班实验地点指导教师时间一、实验目的1、掌握基本的进程同步与互斥算法,理解生产者-消费者问题。

2、学习使用Windows 2000/XP中基本的同步对象,掌握相关API的使用方法。

3、了解Windows 2000/XP中多线程的并发执行机制,实现进程的同步与互斥。

4、设计程序,实现生产者-消费者进程(线程)的同步与互斥;二、实验环境Windows 2000/XP + Visual C++三、实验内容以生产者-消费者模型为依据,在Windows 2000/XP环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

四、设计思路和流程框图生产者进程的功能:生产东西,供消费者消费;消费者进程的功能:消费生产者生产的东西。

生产者生产产品并存入缓冲区供消费者取走使用,消费者从缓冲器内取出产品去消费。

在生产者和消费者同时工作时,必须禁止生产者将产品放入已装满的缓冲器内,禁止消费者从空缓冲器内取产品。

五、源程序(含注释)清单六、测试结果以及实验总结1、通过实验进一步了解了基本的进程同步与互斥算法,理解生产者-消费者问题2、掌握了相关API的使用方法。

3、了解到进程是一个可以拥有资源的基本单位,是一个可以独立调度和分派的基本单位。

而线程是进程中的一个实体,是被系统独立调度和分配的基本单位,故又称为轻权(轻型)进程(Light Weight Process)。

4、了解到同步对象是指Windows中用于实现同步与互斥的实体,包括信号量(Semaphore)、互斥量(Mutex)、临界区(Critical Section)和事件(Events)等。

本实验中使用到信号量、互斥量和临界区三个同步对象。

成绩备注:实验报告文档的名称:姓名_实验编号(例如:张三_1、张三_2);实验报告发送到。

操作系统进程同步与互斥实验报告0204192337

操作系统进程同步与互斥实验报告0204192337

学生实验报告姓名:年级专业班级学号成绩#define N 1 //N定义为临界资源!printf("请输入三个进程:\n"); //初始状态为:临界资源处于空闲状态!loop:scanf("%d %d %d",&a,&b,&c); //输入的进程名为:a,b,c!进程名输入的先后代表进程的访问顺序!if(a==N) //判断进程a是否占据临界资源!若a==N,表明a访问临界资源!{printf("a=%d\n",a); //a正在访问临界资源!printf("b=0,c=0\n"); //b,c不能进入自己的临界区,需等待a释放临界资源!printf(“临界资源正在被进程a访问,进程b,c必须等待.\n”);}else if(b==N){printf("b=%d\n",b); //b正在访问临界资源!printf("a=0,c=0\n"); //a,c不能进入自己的临界区,需等待b释放临界资源!printf(“临界资源正在被进程b访问,进程a,c必须等待.\n”);}5.编译链接所编写的程序,在编译正确的情况下执行程序.6.记录程序执行的结果(如下图所示).注意:初始状态为:临界资源处于空闲状20 10年12 月16 日【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)1.进程a,b,c分别访问临界资源时程序执行的结果如下.(a) (b) (c)2.该程序初始化N为临界资源,根据输入a,b,c,的值是否等于N来判断进程分别是否进入自己的临界区。

当a=N 表明进程a正在访问临界资源。

此时程序执行的输出为:a=1,b=c=0表示进程b,c不能进入自己的临界区。

3.该程序能较好地体现程序并发执行时的一种制约关系-互斥,但不能较好的反映进程的同步关系,所以该算法有待改进,用以同时实现进程的同步和互斥。

操作系统进程同步实验报告

操作系统进程同步实验报告

操作系统进程同步实验报告本实验旨在通过模拟操作系统中进程的同步问题,加深学生对操作系统中进程同步机制的了解和实践能力。

本次实验分为两个部分,第一个部分是使用信号量实现进程同步,第二个部分是使用管程实现进程同步。

第一部分实验:使用信号量实现进程同步本部分实验的目标是使用信号量来实现进程同步,确保资源的互斥访问。

在Linux系统中,信号量是一种用来控制进程同步的机制,可以用于保证共享资源的互斥访问、避免死锁等问题。

具体实验流程如下:1. 定义一个信号量,用于互斥访问共享资源在Linux系统中,使用semget函数可以创建一个信号量集,使用semctl函数可以对信号量进行控制。

```#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define KEY 1234 // 定义信号量的键值int semid; // 定义信号量标识符union semun{int val; // 信号量的初始值struct semid_ds *buf; // IPC_STAT, IPC_SET操作时用ushort *array; // GETALL, SETALL操作时用};void init_sem(){int ret;union semun semunion;// 创建信号量semid = semget(KEY, 1, IPC_CREAT | 0666);if(semid == -1){perror("semget error");exit(1);}2. 定义生产者和消费者进程,并使用信号量来实现同步在生产者和消费者进程中,需要先对信号量进行P操作,即申请资源,然后进行对共享资源的操作,最后再对信号量进行V操作,即释放资源。

本实验中,共享资源是一个循环缓冲区,生产者进程向其中写入数据,消费者进程从中读取数据。

操作系统原理实验报告

操作系统原理实验报告

课 程 论 文作 者:学 号: 0 专业班级:课程名称:操作系统原理 题 目:操作系统实验报告 成 绩:年年 月月 教师评语::操作系统实验报告——进程同步实验(生产者与消费者问题算法实现)1.1.实验目标和要求 进程的同步是操作系统处理机管理的重要内容,本实验要求学生理解生产者与消费者问题模型,掌握解决该问题的算法思想,学会使用同步机制。

题模型,掌握解决该问题的算法思想,学会使用同步机制。

2.2.实验内容 一组生产者向一组消费者提供消息,一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,它们共享一个有界缓冲池,它们共享一个有界缓冲池,生产者向其中投放消息,生产者向其中投放消息,消费者从中取得消息。

假定这些生产者和消费者互相等效,假定这些生产者和消费者互相等效,只要缓冲池未满,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。

送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。

根据进程同步机制,根据进程同步机制,编写一个解决上述问题的可视化程序,可显示缓冲池状态、放数据、取编写一个解决上述问题的可视化程序,可显示缓冲池状态、放数据、取数据等过程。

数据等过程。

缓冲区1 P Q 缓冲区2 缓冲区3 缓冲区n-1 缓冲区n 放消息放消息 N 个缓冲区个缓冲区取消息取消息3.3.实验方法或步骤 3. 1程序类图3. 2采用的同步方法1.1.利用函数利用函数利用函数CreateMutex(NULL,FALSE,NULL)CreateMutex(NULL,FALSE,NULL)CreateMutex(NULL,FALSE,NULL)创建互斥信号量创建互斥信号量创建互斥信号量g_hMutex g_hMutex g_hMutex,表示缓冲区当,表示缓冲区当前的状态,若为前的状态,若为true true true时,则表示缓冲区正被别的进程使用。

三个参数表示的意义分别为:时,则表示缓冲区正被别的进程使用。

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

实验二进程同步一、实验目的:掌握基本的同步算法,理解经典进程同步问题的本质;学习使用Linux的进程同步机制,掌握相关API的使用方法;能利用信号量机制,采用多种同步算法实现不会发生死锁的哲学家进餐程序。

二、实验平台:虚拟机:VMWare12操作系统:kali linux编辑器:Gedit编译器:Gcc三、实验内容:(1)以哲学家进餐模型为依据,在Linux控制台环境下创建5个进程,用semget函数创建一个信号量集(5个信号量,初值为1),模拟哲学家的思考和进餐行为:每一位哲学家饥饿时,先拿起左手筷子,再拿起右手筷子;筷子是临界资源,为每一支筷子定义1个互斥信号量;想拿到筷子需要先对信号量做P操作,使用完释放筷子对信号量做V操作。

伪代码描述:semaphore chopstick[5]={1,1,1,1,1};•第i位哲学家的活动可描述为:do{printf("%d is thinking\n",i);printf("%d is hungry\n",i);wait(chopstick[i]); //拿左筷子wait(chopstick[(i+1) % 5]); //拿右筷子printf("%d is eating\n",i);signal(chopstick[i]); //放左筷子signal(chopstick[(i+1) % 5]); //放右筷子…}while[true];运行该组进程,观察进程是否能一直运行下去,若停滞则发生了什么现象?并分析原因。

(2)解决哲学家进餐问题可采用如下方法:a.仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐;b.至多只允许有4位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐;c.规定奇数号哲学家先拿起他左手的筷子,然后再拿起他右手的筷子,而偶数号哲学家则先拿起他右手的筷子,然后再拿起他左手的筷子。

方法a在示例程序中给出,请用方法b和c写出不会发生死锁的哲学家进餐程序。

(3)设计程序,实现生产者/消费者进程(线程)的同步与互斥。

在该程序中创建4个进程(或线程)模拟生产者和消费者,实现进程(线程)的同步与互斥。

四、实验步骤:一、Linux的信号量机制为了简化对多个信号量的操作,Linux系统中提出了信号量集的概念。

一个信号量集对象中可以容纳多个信号量,System V 信号量的分配和操作是以信号量集为单位的。

1. 进程利用信号量获得共享资源的步骤:a.测试控制该资源的信号量;b.若信号量为正,则进程可以使用该资源;使用资源时,进程将该信号量减1(P操作);不再使用资源时,进程将该信号量值加1(V操作);c.若信号量为0,则进程进入睡眠状态P操作和V操作都原子操作。

2. 创建或打开信号量集semget()系统调用创建一个新信号量集或获取一个既有信号量集的表示符。

函数原型:#include <sys/sem.h>int semget(key_t key, int nsems, int flag);返回值:成功返回信号量集ID,出错返回-1。

nsems信号量集中信号量个数;flags:IPC_CREAT,IPC_EXCL,权限组合;第一个参数key是整数值(唯一非零),不相关的进程可以通过它访问一个信号量,它代表程序可能要使用的某个资源,程序对所有信号量的访问都是间接的,程序先通过调用semget 函数并提供一个键,再由系统生成一个相应的信号标识符(semget函数的返回值),只有semget函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。

如果多个程序使用相同的key值,key将负责协调工作。

第三个参数sem_flags是一组标志,当想要当信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作。

设置了IPC_CREAT标志后,即使给出的键是一个已有信号量的键,也不会产生错误。

而IPC_CREAT | IPC_EXCL则可以创建一个新的,唯一的信号量,如果信号量已存在,返回一个错误。

注意:建立信号量集时每个信号量的初始值不确定。

3. 信号量控制操作semctl()系统调用在一个信号量集或集合中的单个信号量上执行各种控制操作。

函数原型:#include <sys/sem.h>int semctl (int semid, int semnum, int cmd, …/*union semun arg*/)semnum:信号量编号或0,表示对指定信号量做控制操作;cmd: 操作命令,实施的控制操作;第四个参数是union semununion semun{int val;struct semid_ds *buf;unsigned short *array;}例:定义一个信号量集,含3个信号量,初始值分别为(2,5,1)。

semid = semget(IPC_PRIVATE,3,IPC_CREAT|IPC_EXCL|0777);unsigned short vals[3] = {2,5,1};union semnu se;se.array = vals;semclt(semid,0,SETALL,se);4. 信号量集操作semop()系统调用在semid标识的信号量集中的信号量上执行一个或多个up或down操作,可用于进程间的同步和互斥。

函数原型:#include <sys/sem.h>int semop(int semid, struct sembuf *semop, size_t nops);返回:成功返回0,出错返回-1。

Struct sembuf{unsigned sem_num; /*member # in set*/short sem_op; /*operation(negative, 0, positive*/short sem_flg; /*IPC_NOWAIT,SEM_UNDO*/}例:对上文定义的信号量集semid中的3个信号量,分别执行如下操作:1: p(1); 2: p(3); 3: v(3); 其semop的操作语句为:struct sembuf ops[3] = {{0, -1, SEM_UNDO}, {1,-3, SEM_UNDO},{2,3, SEM_UNDO}}; semop(semid, ops ,3);5.组合权限说明0666 文件或目录的所有者、所有者所在组、其他用户对该对象均可读、可写rw-rw-rw- 0777 文件或目录的所有者、所有者所在组、其他用户对该对象均可读、可写、可执行rwxrwxrwx 附:示例程序(左、右两只筷子均可用时才允许拿起筷子)#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdint.h>#include <stdbool.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/wait.h>#ifdef _SEM_SEMUN_UNDEFINEDunion semun{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *__buf;};#endif#define ERR_EXIT(m) \do { \perror(m); \exit(EXIT_FAILURE); \} while(0)int wait_1chopstick(int no,int semid){struct sembuf sb = {no,-1,0};int ret;ret = semop(semid,&sb,1);if(ret < 0) {ERR_EXIT("semop");}return ret;}int free_1chopstick(int no,int semid){struct sembuf sb = {no,1,0};int ret;ret = semop(semid,&sb,1);if(ret < 0) {ERR_EXIT("semop");}return ret;}#define DELAY (rand() % 5 + 1)void wait_for_2chopstick(int no,int semid) {int left = no;int right = (no + 1) % 5;struct sembuf buf[2] = {{left,-1,0},{right,-1,0}};semop(semid,buf,2);}void free_2chopstick(int no,int semid) {int left = no;int right = (no + 1) % 5;struct sembuf buf[2] = {{left,1,0},{right,1,0}};semop(semid,buf,2);}void philosophere(int no,int semid){srand(getpid());for(;;) {#if 0printf("%d is thinking\n",no);sleep(DELAY);printf("%d is hungry\n",no);wait_for_2chopstick(no,semid);printf("%d is eating\n",no);sleep(DELAY);free_2chopstick(no,semid);#elseint left = no;int right = (no + 1) % 5;printf("%d is thinking\n",no);sleep(DELAY);printf("%d is hungry\n",no);wait_1chopstick(left,semid);sleep(DELAY);wait_1chopstick(right,semid);printf("%d is eating\n",no);sleep(DELAY);free_1chopstick(left,semid);free_1chopstick(right,semid);#endif}}int main(int argc,char *argv[]){int semid;semid = semget(IPC_PRIVATE,5,IPC_CREAT | 0666);if(semid < 0) {ERR_EXIT("semid");}union semun su;su.val = 1;int i;for(i = 0;i < 5;++i) {semctl(semid,i,SETVAL,su);}int num = 0;pid_t pid;for(i = 1;i < 5;++i) {pid = fork();if(pid < 0) {ERR_EXIT("fork");}if(0 == pid) {num = i;break;}}philosophere(num,semid);return 0;}五、实验结果。

相关文档
最新文档