操作系统——Windows 线程的互斥与同步

news2024/11/25 20:54:05

、实验题目

Windows 线程的互斥与同步

二、实验目的

(1) 回顾操作系统进程、线程的有关概念,加深对 Windows 线程的理解。

(2) 了解互斥体对象,利用互斥与同步操作编写生产者-消费者问题的并发程序,加深对 P (即 semWait)、V(即 semSignal)原语以及利用 P、V 原语进行进程间同步与互斥操作的理解

三、实验内容(实验原理/运用的理论知识、算法/程序流程图、步骤和方法、关键代码)

生产者消费者问题

步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 5-1 中的程序,编译成可执行

文件。

步骤 2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。

步骤 3:仔细阅读源程序,找出创建线程的 WINDOWS API 函数,回答下列问题:线程的第一

个执行函数是什么(从哪里开始执行)?它位于创建线程的 API 函数的第几个参数中?

步骤 4:修改清单 5-1 中的程序,调整生产者线程和消费者线程的个数,使得消费者数目大与

生产者,看看结果有何不同。察看运行结果,从中你可以得出什么结论?

步骤 5:修改清单 5-1 中的程序,按程序注释中的说明修改信号量 EmptySemaphore 的初始化方

法,看看结果有何不同。

步骤 6:根据步骤 4 的结果,并查看 MSDN,回答下列问题:

1)CreateMutex 中有几个参数,各代表什么含义。

2)CreateSemaphore 中有几个参数,各代表什么含义,信号量的初值在第几个参数中。

3)程序中 P、V 原语所对应的实际 Windows API 函数是什么,写出这几条语句。

4)CreateMutex 能用 CreateSemaphore 替代吗?尝试修改程序 5-1,将信号量 Mutex 完全用

CreateSemaphore 及相关函数实现。写出要修改的语句。

问题回答:

步骤 3:

创建线程的Windows API函数是CreateThread。

线程的第一个执行函数是Producer函数(生产者线程的入口函数)。它位于CreateThread的第三个参数lpStartAddress中。

步骤 4:

调整生产者线程和消费者线程的个数,使得消费者数目大于生产者,可以观察到以下结果:

当消费者线程数目大于生产者线程数目时,消费者线程可能更频繁地等待缓冲区中有产品可消费,因此消费者线程的执行速度可能较慢。

生产者线程可能更频繁地生产产品,因为消费者线程较慢消耗产品,缓冲区中可能较少空位,导致生产者线程等待EmptySemaphore的次数增加。

步骤 5:

修改信号量EmptySemaphore的初始化方法,将第二个参数设置为0,即初始化为0个空位,代码示例:EmptySemaphore = CreateSemaphore(NULL, 0, SIZE_OF_BUFFER, NULL)。

结果将导致所有的生产者线程在开始时无法生产产品,因为EmptySemaphore信号量初始为0,生产者线程在WaitForSingleObject(EmptySemaphore, INFINITE)处被阻塞,等待消费者线程消耗产品。

步骤 6:

CreateMutex中有3个参数,各代表的含义如下:

参数1:lpMutexAttributes,指向SECURITY_ATTRIBUTES结构的指针,用于设置互斥对象的安全属性。可以为NULL,表示使用默认的安全属性。

参数2:bInitialOwner,指示是否为调用线程拥有互斥对象的初始所有权。TRUE表示拥有,FALSE表示未拥有。

参数3:lpName,互斥对象的名称。可以为NULL。

CreateSemaphore中有4个参数,各代表的含义如下:

参数1:lpSemaphoreAttributes,指向SECURITY_ATTRIBUTES结构的指针,用于设置信号量的安全属性。可以为NULL,表示使用默认的安全属性。

参数2:lInitialCount,信号量的初始计数器值,即可用的资源数量。

参数3:lMaximumCount,信号量的最大计数器值,即计数器的上限。

参数4:lpName,信号量的名称。可以为NULL。信号量的初值在第二个参数lInitialCount中。

P、V原语所对应的实际Windows API函数是:

P操作对应的是WaitForSingleObject函数,用于等待一个对象的信号状态。

V操作对应的是ReleaseSemaphore函数,用于增加信号量的计数器值。

CreateMutex可以用CreateSemaphore替代,但需要做一些修改:

将CreateMutex修改为CreateSemaphore,同时修改互斥锁的初始化和使用方法。

使用WaitForSingleObject来替代WaitForSingleObject(mutex, INFINITE),等待信号量的状态。

使用ReleaseSemaphore来替代ReleaseMutex(mutex),释放信号量。

修改代码示例:

// 初始化互斥锁

mutex = CreateSemaphore(NULL, 1, 1, NULL);

// 生产者线程

WaitForSingleObject(emptySemaphore, INFINITE);

WaitForSingleObject(mutex, INFINITE);

// ...

ReleaseSemaphore(mutex, 1, NULL);

// 消费者线程

WaitForSingleObject(fullSemaphore, INFINITE);

WaitForSingleObject(mutex, INFINITE);

// ...

ReleaseSemaphore(mutex, 1, NULL);

注意,由于CreateSemaphore初始化的互斥锁计数器初始值为1,所以这里使用了1作为CreateSemaphore的初始计数器值,并在WaitForSingleObject和ReleaseSemaphore中将第二个参数设置为1。

四、实验结果与分析

 

实验结果:

程序创建了多个生产者线程和消费者线程。

生产者线程负责生产产品,每次生产后将产品放入缓冲区。

消费者线程负责从缓冲区中取出产品并消耗。

生产者和消费者之间通过互斥锁(Mutex)和信号量(EmptySemaphore和FullSemaphore)实现同步和互斥。

实验分析:

在主函数中,首先创建了互斥锁(Mutex)和两个信号量(EmptySemaphore和FullSemaphore)。互斥锁用于保护共享资源的访问,信号量用于控制生产者和消费者的同步。

根据设置的生产者和消费者数量,创建了相应数量的线程,并分别执行Producer和Consumer函数。

生产者线程在每次生产产品之前,首先等待EmptySemaphore信号量,确保缓冲区有可用的位置。然后获取互斥锁Mutex,进行生产操作,将产品放入缓冲区,并释放互斥锁Mutex和FullSemaphore信号量。

消费者线程在每次消耗产品之前,首先等待FullSemaphore信号量,确保缓冲区中有可用的产品。然后获取互斥锁Mutex,进行消耗操作,从缓冲区中取出产品,并释放互斥锁Mutex和EmptySemaphore信号量。

在每个生产者和消费者的操作中,通过输出语句打印相关信息,包括生产的产品号、缓冲区的状态以及消费的产品号。

主函数中的while循环用于控制程序的运行,当按下回车键时,设置p_ccontinue为false,结束生产者和消费者的线程运行。

由于涉及多线程和同步操作,实际运行结果可能因为线程调度和竞态条件的不确定性而有所不同。以上分析是一种可能的情况。

需要注意的是,这段代码在创建信号量时有两种方式的注释,可以根据需要进行修改,观察对程序运行的影响。

总的来说,这个实验通过模拟生产者和消费者的行为,展示了线程间同步和互斥的机制。生产者和消费者通过缓冲区进行交互,确保生产者不会在缓冲区满时继续生产,消费者不会在缓冲区空时继续消耗。通过互斥锁和信号量的合理运用,保证了线程的安全和正确的执行顺序。

五、小结与心得体会

1.多线程编程:该实验涉及多线程编程,通过创建多个线程并使用线程同步机制实现线程间的协调与通信。

2.生产者-消费者模型:该实验基于生产者-消费者模型,生产者生成产品并放入缓冲区,消费者从缓冲区中取出产品进行消费。

3.缓冲区的使用:缓冲区被设计为循环队列,使用数组来表示。生产者和消费者通过维护缓冲区的读写指针(in和out)来实现对缓冲区的访问。

4.线程同步与互斥:为了避免生产者和消费者同时访问缓冲区而导致数据不一致的问题,使用互斥信号量(Mutex)进行互斥操作。同时,通过同步信号量(FullSemaphore和EmptySemaphore)实现生产者和消费者之间的同步。

5.线程间通信:生产者和消费者之间通过信号量进行通信和同步,当缓冲区满时生产者等待,当缓冲区空时消费者等待。

6.通过以上实验,可以深入理解多线程编程的概念和技术,以及生产者-消费者模型在多线程环境下的应用。这对于并发编程和系统设计有着重要的意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Spec] WiFi P2P Discovery

学习资料:Android Miracast 投屏 目录 学习资料:Android Miracast 投屏 P2P discovery Introduction Device Discovery procedures Listen State Search State Scan Phase Find Phase 总结 P2P discovery Introduction P2P发现使P2P设备能够快速…

WiSA Technologies开始接受WiSA E多声道音频开发套件的预订

美国俄勒冈州比弗顿市 — 2023年6月13日 — 为智能设备和下一代家庭娱乐系统提供沉浸式无线声效技术的领先供应商WiSA Technologies股份有限公司(NASDAQ股票代码:WISA)宣布:该公司现在正在接受其WiSA E开发套件的预订。WiSA E使用…

论文不详细解读(一)——MoCo系列

1. MoCo v1 论文名称: Momentum Contrast for Unsupervised Visual Representation Learning 开源地址:https://github.com/facebookresearch/moco 大佬详细解读:https://zhuanlan.zhihu.com/p/382763210 motivation 原始的端到端自监督方…

听说软件测试岗位基本都是女孩子在做?

“听我一朋友说,测试岗位基本都是女孩子做。” 不知道是不是以前“软件测试岗”给人印象是“不需要太多技术含量”的错觉,从而大部分外行认为从业软件测试的人员中女生应占了大多数。比如有人就觉得:软件测试主要是细心活,所以女生…

Python多任务执行方式

一、多任务的执行方式 并发:在一段时间内交替去执行任务(单核CPU)并行:CPU核数大于任务数 二、进程(实现多任务)——操作系统调度 进程是操作系统进行资源分配的基本单元一个程序至少有一个进程&#xf…

极致呈现系列之:EchartsK线图的数据量化

目录 什么是K线图K线图的特性及应用场景K线图的特性K线图的应用场景 Echarts中K线图的常用属性Vue3中创建K线图 什么是K线图 K线图是一种用于展示金融市场中股票、期货、外汇等交易品种价格走势的图表形式。它由一根根的垂直线条和水平线组成,能够直观地显示出一段…

OJ #378 字符串括号匹配2

题目描述 ​ 给出一个字符串,判断其中的左右括号是否匹配。 ​ 注:需同时判断左右圆括号 ( 和 ) ,左右中括号 [和],左右大括号 {和}。 ​ 不需要考虑括号之间的优先级的问题,也就是说,小括号包含大括号&…

NodeJS应届毕业生财务管理系统-计算机毕设 附源码82886

基于VueNodeJS应届毕业生财务管理系统 摘 要 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理。由于现在…

合宙Air724UG Cat.1模块硬件设计指南--看门狗

概述 Air724UG 内部已经自带了看门狗,4秒进行一次喂狗,如果主芯片异常死机,自带的看门狗15秒左右会硬件复位主芯片。 另外主芯片死机情况下,reset键也可以硬重启。 通常情况下不需要外加硬件看门狗,如果对系统稳定性有…

FreeRTOS和uC/OS:选择入手哪个RTOS更合适?

FreeRTOS和uC/OS是两个流行的实时操作系统(RTOS),用于嵌入式系统开发。它们有一些区别,但选择哪个先入手取决于你的需求和项目要求。 复杂度:FreeRTOS是一个相对较简单的RTOS,它专注于提供基本的实时调度和…

西门子Mendix 入门 3

导航页面:用于在应用程序中添加或修改其他页面 创建查看查看和添加公司不同部门的页面 打开导航页面,添加新项目 选择TaskTracke新建一个名为Department_Overview的页面,并选择List作为模板 创建成功 现在转到 Department_Overview页面 链接数…

揭秘2023年项目管理软件排行榜实力榜

在现代的商业世界中,项目管理是必不可少的一个组成部分。为了成功地管理一个项目,项目经理需要实施一种系统化的方法来确保项目在时间和预算的约束下成功。这就需要使用专业的项目管理软件。因此,项目管理软件在商业领域中扮演着至关重要的角…

管理类联考——逻辑——知识篇——分析推理——一、排序——haimian

排序 题型特征 排序题通常是依据大小、时间、名次和前后等条件将几个元素有序地排在若干连续排列的位置上。解题时要找出一个对整个排列起决定作用的条件,然后涉及先后位置的条件尽可能结合起来进行解题。 思维导图 思路点拨 注意选项的模式,如果已经…

阿维塔进攻全场景NCA:“遥遥领先”能否赢得市场买单?

阿维塔正在高阶智驾的落地上奋力探索。 “在阿维塔上面,长安汽车、华为、宁德时代做了非常深层次的合作”,6月15日,阿维塔科技副总裁、首席营销官CMO 李鹏程称。当天,阿维塔邀请媒体走进深圳华为坂田基地的华为智能汽车解决方案展…

Autonomous Vehicles Learning Notes

文章目录 自动驾驶感知传感器多模态传感器融合BEVCorner Cases 缩写 未完待续。。。 自动驾驶 来自:浅谈自动驾驶技术与挑战 L0:主动刹车、盲点监测、车道偏离预警和车身稳定系统都属于 L0 级别的自动驾驶; L1:如车道保持系统&a…

MongoDB聚合查询(二)

MongoDB聚合查询 什么是聚合查询 聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起,按条件分组后,再进行一系列操作(如求和、平均值、最大值、最小值)以返回单个结果。 MongoDB的聚合查询 聚合是…

springboot+vue学生档案借阅管理系统_8xpgg-

随着社会的不断进步与发展,人们对生活质量要求逐步提升。如果开发一款档案管理系统,可以让学生在最短的时间里享受到最好的服务;而开发本系统,又能够提高系统整体工作水平,简化工作程序,这对管理员和学生来…

【算法题】数组系列(找出数组中重复的数字、二维数组中的查找)

算法题 数组系列 一、找出数组中重复的数字1.1、题目1.2、解题思路1(排序法)1.3、解题思路2(hash)1.4、小结 二、二维数组中的查找2.1、题目2.2、理解题目2.3、解题思路2.3.1、暴力枚举2.3.2、二分查找2.3.3、对角线查询&#xff…

【数据结构与算法C++实现】3、排序算法

原视频为左程云的B站教学 以下所有的swap()函数,函数定义为 void swap(int& a, int& b) {int t a;a b;b t; } // 也可以用异或,但不能传入同一个变量,可以是不同变量相同值 void swap(int& a, int& b) {a a ^ b;b a ^ …

极智开发 | 让wsl2读取宿主机usb设备

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文介绍一下 让wsl2读取宿主机usb设备的方法。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:…