实验二 进程(线程)的同步与互斥

合集下载

实验、进程的同步与互斥——生产者消费者

实验、进程的同步与互斥——生产者消费者

实验、进程的同步与互斥——⽣产者消费者1. 1. 实验⽬的两个或两个以上的进程,不能同时进⼊关于同⼀组共享变量的临界区域,否则可能发⽣与时间有关的错误,这种现象被称作进程互斥。

对CPU的速度和数⽬不做出任何假设的前提下,并发进程互斥访问临界资源,是⼀个较好的解决⽅案。

另外,还需要解决异步环境下的进程同步问题。

所谓异步环境是指:相互合作的⼀组并发进程,其中每⼀个进程都以各⾃独⽴的、不可预知的速度向前推进;但它们⼜需要密切合作,以实现⼀个共同的任务,即彼此“知道”相互的存在和作⽤。

实验⽬的:分析进程争⽤资源的现象,学习解决进程同步与互斥的⽅法。

本实验属于设计型实验,实验者可根据⾃⾝情况选⽤合适的开发环境和程序架构。

1. 2. 实验原理信号量的PV操作与处理相关,P表⽰通过的意思,V表⽰释放的意思。

1962年,狄克斯特拉离开数学中⼼进⼊位于荷兰南部的艾恩德霍芬技术⼤学(Eindhoven Technical University)任数学教授。

在这⾥,他参加了X8计算机的开发,设计与实现了具有多道程序运⾏能⼒的操作系统——THE Multiprogramming System。

THE是艾恩德霍芬技术⼤学的荷兰⽂Tchnische Hoogeschool Eindhov –en的词头缩写。

狄克斯特拉在THE这个系统中所提出的⼀系统⽅法和技术奠定了计算机现代操作系统的基础,尤其是关于多层体系结构,顺序进程之间的同步和互斥机制这样⼀些重要的思想和概念都是狄克斯特拉在THE中⾸先提出并为以后的操作系统如UNIX等所采⽤的。

为了在单处理机的情况下确定进程(process)能否占有处理机,狄克斯特拉将每个进程分为“就绪”(ready)、“运⾏”(running)和“阻塞”(blocking)三个⼯作状态。

由于在任⼀时刻最多只有⼀个进程可以使⽤处理机,正占⽤着处理机的进程称为“运⾏”进程。

当某进程已具备了使⽤处理机的条件,⽽当前⼜没有处理机供其使⽤,则使该进程处于“就绪”状态。

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

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

进程的同步与互斥实验报告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 -。

详解进程同步与互斥机制

详解进程同步与互斥机制

详解进程同步与互斥机制⽬录⼀、什么是进程同步⼆、什么是进程互斥三、常见的进程同步与互斥机制⼀、什么是进程同步在多道批处理系统中,多个进程是可以并发执⾏的,但由于系统的资源有限,进程的执⾏不是⼀贯到底的,⽽是⾛⾛停停,以不可预知的速度向前推进,这就是进程的异步性。

那么,进程的异步性会带来什么问题呢?举个例⼦,如果有 A、B 两个进程分别负责读和写数据的操作,这两个线程是相互合作、相互依赖的。

那么写数据应该发⽣在读数据之前。

⽽实际上,由于异步性的存在,可能会发⽣先读后写的情况,⽽此时由于缓冲区还没有被写⼊数据,读进程 A 没有数据可读,因此读进程 A 被阻塞。

进程同步(synchronization)就是⽤来解决这个问题的。

从上⾯的例⼦我们能看出,⼀个进程的执⾏可能影响到另⼀个进程的执⾏,所谓进程同步就是指协调这些完成某个共同任务的并发线程,在某些位置上指定线程的先后执⾏次序、传递信号或消息。

再举个⽣活中的进程同步的例⼦,你想要喝热⽔,于是你打了⼀壶⽔开始烧,在这壶⽔烧开之前,你只能⼀直等着,⽔烧开之后⽔壶⾃然会发⽣响声提醒你来喝⽔,于是你就可以喝⽔了。

就是说⽔烧开这个事情必须发⽣在你喝⽔之前。

注意不要把进程同步和进程调度搞混了:进程调度是为了最⼤程度的利⽤ CPU 资源,选⽤合适的算法调度就绪队列中的进程。

进程同步是为了协调⼀些进程以完成某个任务,⽐如读和写,你肯定先写后读,不能先读后写吧,这就是进程同步做的事情了,指定这些进程的先后执⾏次序使得某个任务能够顺利完成。

⼆、什么是进程互斥同样的,也是因为进程的并发性,并发执⾏的线程不可避免地需要共享⼀些系统资源,⽐如内存、打印机、摄像头等。

举个例⼦:我们去学校打印店打印论⽂,你按下了 WPS 的 “打印” 选项,于是打印机开始⼯作。

你的论⽂打印到⼀半时,另⼀位同学按下了 Word 的 “打印” 按钮,开始打印他⾃⼰的论⽂。

想象⼀下如果两个进程可以随意的、并发的共享打印机资源,会发⽣什么情况?显然,两个进程并发运⾏,导致打印机设备交替的收到 WPS 和 Word 两个进程发来的打印请求,结果两篇论⽂的内容混杂在⼀起了。

线程同步和互斥概念

线程同步和互斥概念

线程同步和互斥概念在多线程编程中,线程同步和互斥是非常重要的概念。

线程同步指的是多个线程在执行过程中的协调和合作,以达到共同的目标。

而线程互斥则是指多个线程在访问共享资源时的互相排斥,以保证数据的一致性和正确性。

一、线程同步线程同步是指多个线程之间的协调和合作,以达到共同的目标。

在多线程编程中,线程同步可以通过各种机制来实现,例如锁、信号量、事件等。

1. 锁机制锁机制是最常见的线程同步机制之一。

锁机制可以保证在同一时间只有一个线程可以访问共享资源,其他线程需要等待锁的释放才能访问。

常见的锁有互斥锁、读写锁等。

例如,在一个多线程环境下,多个线程需要访问同一个全局变量,为了保证数据的一致性和正确性,可以使用互斥锁来实现线程同步。

2. 信号量机制信号量机制是另一种常见的线程同步机制。

信号量可以用来控制并发线程的数量,以达到线程同步的目的。

常见的信号量有二元信号量和计数信号量。

例如,在一个多线程环境下,多个线程需要访问同一个共享资源,为了保证数据的一致性和正确性,可以使用计数信号量来控制并发线程的数量。

3. 事件机制事件机制是一种高级的线程同步机制,可以用来实现线程之间的通信和协调。

事件机制通常包括事件对象、事件等待和事件通知等。

例如,在一个多线程环境下,多个线程需要协调完成一项任务,可以使用事件机制来实现线程同步。

二、线程互斥线程互斥是指多个线程在访问共享资源时的互相排斥,以保证数据的一致性和正确性。

在多线程编程中,线程互斥可以通过各种机制来实现,例如锁、信号量、事件等。

1. 锁机制锁机制可以用来实现线程互斥。

在同一时间只有一个线程可以获得锁,其他线程需要等待锁的释放才能访问共享资源。

例如,在一个多线程环境下,多个线程需要访问同一个全局变量,为了保证数据的一致性和正确性,可以使用互斥锁来实现线程互斥。

2. 信号量机制信号量机制也可以用来实现线程互斥。

通过设置信号量的初始值为1,可以保证只有一个线程可以访问共享资源。

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

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

操作系统实验进程同步与互斥操作系统实验进程同步与互斥实验目的1.掌握进程同步和互斥原理,理解生产者-消费者模型;2.学习Windows2000/xp中的多线程并发执行机制;3.学习使用Windows SDK解决读者-写者问题。

试验内容1依据生产者-消费者模型,在Windows 2000/xp环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥,分析、熟悉生产者消费者问题仿真的原理和实现技术。

(见附件2)试验内容2参考实验内容1和附件2伪码,编程解决读者-写者问题的程序。

(具体要求和读写者问题原始伪码内容见附件1)相关知识Windows 2000/XP的线程控制CreateThread完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。

ExitThread用于结束当前线程。

SuspendThread可挂起指定的线程。

ResumeThread可激活指定线程,它的对应操作是递减指定线程的挂起计数,当挂起计数减为0时,线程恢复执行。

Windows 2000/XP的进程互斥和同步在Windows 2000/XP中提供了临界区、互斥对象、信号量对象同步对象和相应的系统调用,用于进程和线程同步。

临界区对象(Critical Section)只能用于在同一进程内使用的临界区,同一进程内各线程对它的访问是互斥进行的。

相关API包括:InitializeCriticalSection对临界区对象进行初始化;EnterCriticalSection等待占用临界区的使用权,得到使用权时返回;TryEnterCriticalSection非等待方式申请临界区的使用权;申请失败时,返回0;LeaveCriticalSection释放临界区的使用权;DeleteCriticalSection释放与临界区对象相关的所有系统资源。

互斥对象(Mutex)互斥对象相当于互斥信号量,在一个时刻只能被一个线程使用。

线程同步和互斥的区别

线程同步和互斥的区别

线程同步和互斥的区别
1. 互斥是指某⼀资源同时只允许⼀个访问者对其进⾏访问,具有唯⼀性和排它性。

但互斥⽆法限制访问者对资源的访问顺序,即访问是
⽆序的。

2. 同步是指在互斥的基础上(⼤多数情况),通过其它机制实现访问者对资源的有序访问。

3. 同步其实已经实现了互斥,所以同步是⼀种更为复杂的互斥。

4. 互斥是⼀种特殊的同步。

所谓互斥,就是不同线程通过竞争进⼊临界区(共享的数据和硬件资源),为了防⽌访问冲突,在有限的时间内只允许其中之⼀独占性的使⽤共享资源。

如不允许同时写
同步关系则是多个线程彼此合作,通过⼀定的逻辑关系来共同完成⼀个任务。

⼀般来说,同步关系中往往包含互斥,同时对临界区的资源会按照某种逻辑顺序进⾏访问。

如先⽣产后使⽤
总的来说,两者的区别就是:
互斥是通过竞争对资源的独占使⽤,彼此之间不需要知道对⽅的存在,执⾏顺序是⼀个乱序。

同步是协调多个相互关联线程合作完成任务,彼此之间知道对⽅存在,执⾏顺序往往是有序的。

lock与unlock⽅法,替换synchronized,这就是互斥锁的体现。

消费者⽣产者模式就是同步锁的体现。

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

实验二 进程(线程)的同步与互斥一、实验目的1. 掌握基本的同步与互斥算法,理解生产者消费者模型。

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

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

二、实验内容1. 实验内容以生产者/消费者模型为依据,在Windows 环境下创建一个控制台进程,在该进程中创建n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

2. 实验要求● 学习并理解生产者/消费者模型及其同步/互斥规则; ● 学习了解Windows 同步对象及其特性; ● 熟悉实验环境,掌握相关API 的使用方法;● 设计程序,实现生产者/消费者进程(线程)的同步与互斥;三、相关API 的功能及使用我们利用Windows SDK 提供的API 编程实现实验题目要求,而VC 中包含有Windows SDK 的所有工具和定义。

要使用这些API ,需要包含堆这些函数进行说明的SDK 头文件——最常见的是Windows.h(特殊的API 调用还需要包含其他头文件)。

下面给出的是本实验使用到的API 的功能和使用方法简单介绍。

(1) CreateThread● 功能——创建一个在调用进程的地址空间中执行的线程 ● 格式HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParamiter,Buffer(共享内存)生产者消费者DWORD dwCreationFlags,Lpdword lpThread );●参数说明lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。

dwStackSize——定义原始堆栈大小。

lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型定义的函数。

lpParamiter——定义一个给进程传递参数的指针。

dwCreationFlags——定义控制线程创建的附加标志。

lpThread——保存线程标志符(32位)(2) CreateMutex●功能——创建一个命名或匿名的互斥量对象●格式HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName);●参数说明lpMutexAttributes——必须取值NULL。

bInitialOwner——指示当前线程是否马上拥有该互斥量(即马上加锁)。

lpName——互斥量名称。

(3) CreateSemaphore●功能——创建一个命名或匿名的信号量对象●格式HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCTSTR lpName );●参数说明lpSemaphoreAttributes——必须取值NULL。

lInitialCount——信号量的初始值。

该值大于等于0,但小于等于lMaximumCount指定的最大值。

lMaximumCount——信号量的最大值。

lpName——信号量名称。

(4) WaitForSingleObject●功能——使程序处于等待状态,直到信号量hHandle出现(即其值大于0)或超过规定的等待时间●格式DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);●参数说明hHandle——信号量指针。

dwMilliseconds——等待的最长时间(INFINITE为无限等待)。

(5) ReleaseSemaphore●功能——对指定信号量加上一个指定大小的量。

成功执行则返回非0值●格式BOOL ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lppreviousCount );●参数说明hSemaphore——信号量指针。

lReleaseCount——信号量的增量。

lppreviousCount——保存信号量当前值。

(6) ReleaseMutex●功能——打开互斥锁,即把互斥量加1。

成功调用则返回0●格式BOOL ReleaseMutex(HANDLE hMutex);●参数说明hMutex——互斥量指针。

四、示例程序//定义一个结构体用于存储线程的信息struct ThreadInfo{int serial; //线程号char entity; //线程类别(生产者或消费者)double delay; //等待时间double persist; //操作时间};//生产者void Producer(void *p){//定义变量用于存储当前线程的信息DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);while( running ){//P操作cout<<"生产者线程"<<m_serial<<" 请求生产."<<endl;WaitForSingleObject(g_hEmptySemaphore,INFINITE);cout<<"生产者线程"<<m_serial<<" 请求独占缓冲区."<<endl;WaitForSingleObject(g_hMutex,INFINITE);Sleep(m_delay); //延迟等待//生产一个产品cout<<"生产者线程"<<m_serial<<" 生产"<<++ProductID <<" 号产品成功." <<endl;cout<<"生产者线程"<<m_serial<<" 请求将产品"<<ProductID<<" 投入缓冲区."<<endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in+1)%SIZE_OF_BUFFER;Sleep(m_persist); //操作等待cout<<"生产者线程"<<m_serial<<" 将产品"<<ProductID<<" 投入缓冲区中成功."<<endl;//输出缓冲区当前的状态cout<<"****************************"<<endl<<"\n当前缓冲区情况如图(■代表已有产品,□代表没有产品): "<<endl;for (int i = 0;i<10;i++){if( g_buffer[i]>0 ) cout<<"■";else cout<<"□";}cout<<"\n\n****************************\n"<<endl;//V操作ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hFullSemaphore,1,NULL);}}//消费者void Consumer(void *p) {DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial ;m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);while( running ){//P操作cout<<"消费者线程"<<m_serial<<" 请求消费."<<endl;WaitForSingleObject(g_hFullSemaphore,INFINITE);cout<<"消费者线程"<<m_serial<<" 请求独占缓冲区."<<endl;WaitForSingleObject(g_hMutex,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout<<"消费者线程"<<m_serial<<" 请求取出一个产品."<<endl;ConsumeID = g_buffer[out];g_buffer[out]=0;out = (out+1)%SIZE_OF_BUFFER;cout<<"消费者线程"<<m_serial<<" 取出产品"<<ConsumeID<<" 成功."<<endl;//消耗一个产品cout<<"消费者线程"<<m_serial<<" 开始消费消费产品" <<ConsumeID<<"."<<endl;Sleep(m_persist);cout<<"消费者线程"<<m_serial<<" 消费产品" <<ConsumeID<<" 成功."<<endl;//输出缓冲区当前的状态cout<<"****************************"<<endl<<"\n当前缓冲区情况如图: "<<endl;for ( int i= 0;i<10;i++){if(g_buffer[i]>0 )cout<<"■";else cout<<"□";}cout<<"\n\n****************************\n"<<endl;//V操作ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hEmptySemaphore,1,NULL);}}五、实验结果六、实验结果分析1、记录生产者和消费者的同步执行过程线程号线程类别延迟时间操作时间操作请求缓冲区请求生产(消费)结果1 P 12 请求生产请求独占(在2前)生产成功2 P 2 6 请求生产请求独占未生产3 C45 请求消费无未消费4 C56 请求消费无未消费5 C 3 2 无无未消费2、分析Producer函数和Consumer函数的功能,并画出对应的程序流程图。

相关文档
最新文档