文档库 最新最全的文档下载
当前位置:文档库 › linux下利用互斥实现线程访问共享资源(含源文件)

linux下利用互斥实现线程访问共享资源(含源文件)

linux下利用互斥实现线程访问共享资源(含源文件)
linux下利用互斥实现线程访问共享资源(含源文件)

“计算机操作系统”课程设计大作业

一、实验题目: linux下利用互斥实现线程访问共享资源

二、实验目的:掌握线程创建和终止,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的通信。

三、实验内容

事先了解操作系统中经典的生产者-消费者问题,安装linux虚拟机(可以用virtualbox或者vmware软件)。在linux下创建三个生产者线程(P1,P2,P3)和一个消费者线程(C1),生产者和消费者线程共享一个长度为2KB的环型公共缓冲区,生产者向缓冲区写入消息,消费者从缓冲区中取走消息显示到屏幕。只要缓冲区未满,生产者可将消息送入缓冲区;只要缓冲区未空,消费者可从缓冲区取走一个消息。

每个消息具下列结构格式:

消息长度(1个字节),消息内容(n个字节)。

每个生产者每隔2秒生产一个消息加入缓冲区,并把消息产生时间和内容记录在一个文本文件中。P1每次生产的数据为26个大写字母, P2每次生产的数据为26个小写字母,P3每次生产的数据为10个阿拉伯数字。

消费者C1每隔3秒读取缓冲区中的一个消息并将消息内容显示到屏幕上。

用两种方法(不采线程用互斥和采用线程互斥技术)编写上述功能的程序,对比两种程序运行结果有何区别?不采线程用互斥时存在什么问题?

备注:编程中用到的函数

创建线程函数:pthread_create

互斥锁初始化:pthread_mutex_init

互斥锁加锁:pthread_mutex_lock

互斥锁解锁:pthread_mutex_unlock

四、实验要求:

每人完成一份大作业实验报告。报告分设计思想、数据定义、处理流程、源程序、运行结果截图、设计体会等部分。

1)给出数据定义和详细说明;

2)给出实现思想和设计流程;

3)调试完成源程序;

4)屏幕观察运行结果;

5)总结自己的设计体会;

编程语言及操作系统平台不限。

五、提交内容

本大作业每个人必须单独完成。最后需提交的内容包括:源程序(关键代码需要注释说明)、可运行程序、算法思路及流程图、心得体会。大作业必须以WORD附件的形式提交。

大作业严禁抄袭。发现抄袭一律以不及格论。大作业内容要完整,一定要有算法思路、流程图、心得体会、运行输出信息截屏等内容,如果只提交源代

码则大作业成绩记为不合格。

2016-10-20

linux下利用互斥实现线程访问共享资源

一、原理的理解

生产者-消费者问题是一个经典的线程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。在同一个线程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

多个生产/消费者在有界缓冲上操作。它利用N个字节的共享内存作为有界循环缓冲区,利用写一字符模拟放一个产品,利用读一字符模拟消费一个产品。当缓冲区空时消费者应阻塞睡眠,而当缓冲区满时生产者应当阻塞睡眠。一旦缓冲区中有空单元,生产者线程就向空单元中入写字符,并报告写的内容和位置。一旦缓冲区中有未读过的字符,消费者线程就从该单元中读出字符,并报告读取位置。生产者不能向同一单元中连续写两次以上相同的字符,消费者也不能从同一单元中连续读两次以上相同的字符。

二、完成步骤

1、思路分析

本作业是完善课件上的线程综合实例的练习生产者-消费者问题,重构这个程序的框架,完成性能分析,使之进一步理解掌握Linux下线程的同步、通信以及互斥和多线程的安全问题。

一般情况下,解决互斥方法常用信号量和互斥锁,即semaphore和mutex,而解决这个问题,多采用一个类似资源槽的结构,每个槽位标示了指向资源的指针以及该槽位的状态,生产者和消费者互斥查询资源槽,判断是否有产品或者有空位可以生产,然后根据指针进行相应的操作。同时,为了告诉生产者或者消费者资源槽的情况,还要有一个消息传送机制,无论是管道还是线程通信。

然而,本次试验有几个特殊的要求:

A、循环缓冲。

B、除了stderr,stdout等外,只用小于2个的互斥锁、

C、放弃资源槽分配机制,采用额外的数据结构。

D、生产者一直持续生产,形成生产消费的良性循环。

首先,使用一个互斥锁,意味着资源槽机制就不能使用了。因为资源槽虽以用一个互斥锁完成,但是需要有额外的通信,如果使用管道通信,则管道也必须是互斥,这就不满足1个互斥锁的要求。其次,要求生产者一直生产,这就否定了另外一种方法:消费者、生产者的位置均平等,消费者消费的时候生产者不能生产,生产者生产的时候消费者不能消费。因此,就需要采用A要求,也就是循环链表的形式。

为了保证互斥要求,需要定义一个数据结构,这个数据结构包含两个指针,一个读一个写,同时有一个资源数目量,告诉生产者和消费者是否可以生产或者消费。由于该数据结构很小,因而可以对此结构互斥访问。同时,对于每组数据,都有一个标志位,表示此组数据是否被占用,生产者和消费者均可以先占用此位置然后完成相应的操作。

当消费者互斥访问此结构时,首先判断是否有数据可以取,如果没有,直接等待,若有数据可取,先更改标志位占用此数据,并将资源数目-1。然后交出互斥,把数据拷贝到自己缓冲区内,清空数据。当生产者访问时,首先判断有没有空位可以生产,如果没有,直接等待,若有数据可以生产,先判断该位是否被占用,如果没被占用,则占用此位置进行生产。生产完成后,将占用位改为未占用,同时将资源数目+1。这个过程可以如图所示:

2、重要函数和数据结构

(1)数据结构

(2)函数说明

3、程序流程图

A、主函数

B、统计线程

C、生产者线程

D、消费者线程

三、实验数据

1、程序运行截图

虚拟机:VMware Workstation7.0,win7;硬件:i3,2G DDR1333;编译:gcc product.c –pg –lpthread;报告生成:gprof –b。

运行时截图:

CPU占用情况(无额外等待):

2、原始数据

由于程序要求使用gprof进行分析,而在机器配置较好的情况下,使用gprof可能分析不出每个函数执行时间,甚至连函数都分析不全,因而在实际代码中添加了一些空循环来增加cpu占用。

为了更便于观察,首先假设如下场景:消费者、生产者在执行各自动作前,均usleep(1),同时,消费者在成功消费之后,也会usleep(3)来为其他消费者让位。同时,也将测试没有任何等待的数据。程序内有一计时线程,每个一秒会显示一次生产消费情况,当60秒后程序

四、结果分析

1、资源消耗的分析

首先,是整体的资源消耗,由于结构问题,生产者和消费者的实质都是while(1)的循环,这意味着如果不插入等待时间的话,任何一种方案,无论生产者消费者的数目,运行起来都可以让CPU的占用达到100%,即使线程的资源开销要小于进程。

另外,就是本题假设的情况,在有等待的情况下,我们假定生产者生产东西需要更多的时间,这个时间为20000的一个空循环,而消费者只需要6000的空循环即可。以3消费者10生产者,有等待这组数据为例,生产者和消费者的CPU占用比例差不多为94:6,即便是3*4:10也只是12:10而已,但是实际上生产者的CPU占用比例很高,这和生产者的操作有关。生产者完成的任务是将一组数据循环写入一个数组内,而这个数组的长度为1024,这本身就需要一定的资源消耗,而消费者只是执行一个strcpy。尽管如此,在总共60秒的运行中,几个函数的CPU占用时间也只是1.6s而已。

接下来,是没有等待的情况。以5生产者,20消费者,40缓冲区的情况为例,从分析报告可以得出,消费者和生产者的CPU占用比大概为4:1,但是从CPU占用时间来看,生产者的3.5秒还比消费者的2.8秒要多,这也说明了生产者实际的工作更占用CPU资源,而绝大多数时间都花在对信号量的等待上。

另外,需要考虑的是互斥操作的开销问题,加锁和解锁都是原子动作,可以互斥完成,因而理论上占用的CPU资源应该非常少。以3消费者10生产者,无等待这组数据的运行结果为例,生产者成功的次数大概在10的3次方级别,而失败的次数确高达10的9次方,从程序运行过程可以得知,失败的操作也包括加锁、访问数量位、解锁这些,从数字的比较我们也可以看出这些原子操作的速度之快。因而,个人认为,在线程数量不是很大的情况下,

课件中给的程序的多锁操作并不会对程序的性能造成太过明显的影响。

由于性能原因,并未给出更多数据的测试报告,而影响这个性能的主要原因是大量的printf,包括清屏、光标重定位、显示文字等,这才是影响整个程序性能的真正原因。

2、具体应用情况

生产者-消费者是一个很广泛的问题,代表了多线程互斥访问共享资源,以及线程之间

Linux系统与网络管理试题09(试卷)

Linux系统与网络管理试卷 考试科目:Linux系统与网络管理试卷代号: B 适用对象:使用学期:2013-2014-1 共4道题总分100分共3页 考生须知: 1)姓名必须写在装订线左侧,其它位置一律作废。 2)请先检查是否缺页,如缺页应向监考教师声明,否则后果由考生负责。 3)答案一律写在答题纸上,可不抄题,但要标清题号。 监考须知:请将两份题签放在上层随答题纸一起装订。 一、填空题(20空,每空2分,共40分) 1.Linux与其他操作系统的最大区别是()。 2.swap交换空间,相当于Windows上的()如果计算机的内存为2GB,则一般需要将交换分区容量设置为()至()。 3.Linux的GNOME菜单的应用程序子菜单位相当于Windows的()菜单中的()。 4.group文件用于保存Linux中组的信息,每一行代表一个组的()数据。 5.Linux系统中文件的属性可以使用( )查看。 6.创建逻辑卷有多种方法,可以在系统安装时创建;也可以在系统安装好后用指令创建与管理,或者在桌面环境中,用()创建与管理。 7.httpd.conf文件中MinSpareThreads表示最小空闲线程数,默认值是()。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的()线程。 8.执行( )命令查看nfs服务器可挂载的目录。 9.邮件服务器在工作时,发件人使用()撰写邮件,完成邮件编辑后进行提交。提交后()使用()协议,将邮件传给发件人所在域的()。 10.一台标准的SendMail服务器,需要安装包括()、()

Linux系统与网络管理 和()等服务器端软件,及()或其他MUA服务程序。 二、选择题(10小题,每小题2分,共20分) 1.UNIX是()操作系统。 A.单用户单任务B.多用户单任务 C.单用户多任务D.多用户多任务 2.()目录是定义Apache服务器站点存放目录; A./var B./var/www C./lib D./www 3.()不是Linux的GNOME桌面环境中“外观首选项”工具提供的配置桌面的各个外观的功能的选项卡。 A.主题B.背景 C.字体D.屏幕保护 4.如果不想退出普通用户,重新用root用户登录,就必须使用()命令切换到root。 A.su B.id C.who D.lastb 5.()命令是linux系统标准的进程查看工具,通过它可查看系统中进程的详细信息 A.ls B.Pstree C.ps D.Top 6.在使用物理RAID5方式工作时,至少需要()块硬盘。 A. 1 B. 2 C. 3 D. 4 7. 用于文件系统直接修改文件权限管理命令为:()。 A. chown B. chgrp C. chmod D. umask 8.Samba的主配置文件是(),默认位于/etc/samba/目录下。 A.smb.conf B.samba.conf C.smb.con D.samba.con

4:一个经典的多线程同步问题汇总

一个经典的多线程同步问题 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。 要求: 1.子线程输出的线程序号不能重复。 2.全局变量的输出必须递增。 下面画了个简单的示意图: 分析下这个问题的考察点,主要考察点有二个: 1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步。 2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥。 下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。 //经典线程同步互斥问题 #include #include #include long g_nNum; //全局资源 unsigned int__stdcall Fun(void *pPM); //线程函数 const int THREAD_NUM = 10; //子线程个数 int main() { g_nNum = 0;

HANDLE handle[THREAD_NUM]; int i = 0; while (i < THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); i++;//等子线程接收到参数时主线程可能改变了这个i的值} //保证子线程已全部运行结束 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); return 0; } unsigned int__stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来int nThreadNum = *(int *)pPM; //子线程获取参数 Sleep(50);//some work should to do g_nNum++; //处理全局资源 Sleep(0);//some work should to do printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum); return 0; } 运行结果:

进程同步机制与互斥-生产者消费者问题

学习中心: 专业: 年级:年春/秋季 学号: 学生: 题目:进程同步与互斥生产者-消费者问题 1.谈谈你对本课程学习过程中的心得体会与建议? 转眼间,学习了一个学期的计算机操作系统课程即将结束。在这个学期中,通过老师的悉心教导,让我深切地体会到了计算机操作系统的一些原理和具体操作过程。在学习操作系统之前,我只是很肤浅地认为操作系统只是单纯地讲一些关于计算机方面的操作应用,并不了解其中的具体操作过程 1.1设计思路 在这次设计中定义的多个缓冲区不是环形循环的,并且不需要按序访问。其中生产者可以把产品放到某一个空缓冲区中,消费者只能消费被指定生产者生产的产品。本设计在测试用例文件中指定了所有生产和消费的需求,并规定当共享缓冲区的数据满足了所有有关它的消费需求后,此共享才可以作为空闲空间允许新的生产者使用。

本设计在为生产者分配缓冲区时各生产者之间必须互斥,此后各个生产者的具体生产活动可以并发。而消费者之间只有在对同一个产品进行消费时才需要互斥,它们在消费过程结束时需要判断该消费者对象是否已经消费完毕并释放缓冲区的空间。 1.2程序流程图 1.3基本内容 在设计程序时主要有三个主体部分、三个辅助函数和一个数据结构。 其中主体部分为一个主函数main(),用于初始化缓冲区和各个同步对象,并完成线程信息的读入,最后根据该组的线程记录启动模拟线程,并等待所有线程的运 Y

行结束后退出程序; 生产者函数Produce()和消费者函数Consume(),生产者和消费者函数运行于线程中完成对缓冲区的读、写动作,根据此处生产消费的模型的特点,生产者和消费者之间通过使用同步对象实现了生产和消费的同步与互斥,是本实验的核心所在。 另外三个辅助性函数被生产者和消费者函数调用,是上述生产和消费函数中对缓冲区进行的一系列处理。 3)在实现本程序的消费生产模型时,具体的通过如下同步对象实现互斥: ①设一个互斥量h_mutex,以实现生产者在查询和保留缓冲区内的下一个位置时进行互斥。 ②每一个生产者用一个信号量与其消费者同步,通过设置h_Semaphore[MAX_THREAD_NUM]信号量 ③数组实现,该组信号量用于相应的产品已产生。同时用一个表示空缓冲区

用信号量实现线程同步与互斥

用信号量实现线程同步与互斥 一、相关Win32 API函数 1、创建线程 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); 函数作用:在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄。 各参数含义: ?lpThreadAttributes:指向一个SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为NULL; ?dwStackSize:指定了线程的堆栈深度,一般都设置为0; ?lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。 一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是线程函数 名;函数名称没有限制,但是必须以下列形式声明:DWORD WINAPI ThreadProc (PVOID pParam) ; ?lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数; ?dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产 生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用; ?lpThreadId:该参数返回所创建线程的ID。 如果创建成功则返回线程的句柄,否则返回NULL。 例如: for (int i=0;i

Linux网络管理及应用课后习题参考答案

Linux 网络管理及应用 习题参考答案 第1章Linux网络操作系统 1.Linux的创始人是谁? 答:Linus Torvalds 2.Linux与Unix操作系统有什么关系? 答:Linux是一种类Unix操作系统,完全与POSIX标准兼容,是该标准的一种实现。 3.Linux与GNU项目是什么关系?它是开源软件吗?是自由软件吗? 答:Linux是一个操作系统内核,并不是一个完整的操作系统;GNU项目是面向开发一个操作系统,采用了Linux作为其系统内核。Linux遵守GNU GPL协议,是自由软件,同时它也是开源软件。 4.开源软件与自由软件有什么区别与联系? 答:自由软件指得是对于软件所拥有的“自由”的权利,包括三种自由;开源软件是一种软件开发方法,面向建立高质量软件。用户可以获得源代码是这两者共同之处。 5.安装Linux一般如何分区?选择哪种文件系统? 答:一般至少分为两个区:根文件系统分区和交换分区。根分区一般选择ext3格式的文件系统,交换分区采用swap格式。 6.Linux支持哪几种安装方式? 答:Linux支持多种安装方式:光盘、网络、本地磁盘等。 7.Linux系统中一个文件的全路径为/etc/passwd,表示了文件的哪些信息? 答:表示了文件的位置和文件的命名两部分信息。 8.什么是虚拟机?为什么要使用虚拟机? 答:虚拟机是利用软件虚拟技术虚拟一个计算机硬件环境的软件技术。使用虚拟机可以让一台高性能的计算机充分发挥其硬件的性能,提高系统的利用率;虚拟机也适合需要频繁更换使用不同操作系统的情况,如软件测试、教育等。 9.VMWare虚拟机中可以安装哪些操作系统? 答:可以安装微软Windows系列操作系统、Linux的多种发行版、MSDOS等许多操作系统。

操作系统 实验 五 线程间的互斥与同步

实验五线程间的互斥与同步 实验学时:2学时 实验类型:验证、设计型 一、实验目的 理解POSIX线程(Pthread)互斥锁和POSIX信号量机制,学习它们的使用方法;编写程序,实现多个POSIX线程的同步控制。 二,实验内容 创建4个POSIX线程。其中2个线程(A和B)分别从2个数据文件(data1.txt和data2.txt)读取10个整数. 线程A和B把从文件中读取的逐一整数放入一个缓冲池. 缓冲池由n个缓冲区构成(n=5,并可以方便地调整为其他值),每个缓冲区可以存放一个整数。另外2个线程,C和D,各从缓冲池读取10数据。线程C、D每读出2个数据,分别求出它们的和或乘积,并打印输出。 提示:在创建4个线程当中,A和B是生产者,负责从文件读取数据到公共的缓冲区,C和D是消费者,从缓冲区读取数据然后作不同的计算(加和乘运算)。使用互斥锁和信号量控制这些线程的同步。不限制线程C和D从缓冲区得到的数据来自哪个文件。 在开始设计和实现之前,务必认真阅读课本6.8.4节和第6章后面的编程项目——生产者-消费者问题。

三,实验要求 按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。 四,实验设计 1,功能设计 根据实验要求,主程序需要创建四个线程,两个线程负责从文件读取数据到缓冲区,两个线程负责将缓冲区的数据做数学运算。由于同一个进程中的各个线程共享资源,可以用一个二维数组的全局变量作为公共缓冲区,同时还需要一个整形全局变量size用来做数组的索引。读线程的运行函数打开不同的文件并从中读取数据到二维数组中,每次写入数组后size加一。运算线程从二维数组中读数并做运算,每次读数之前size减一。本题的关键在于如何使用信号量保证进程的同步与互斥。在运算线程从缓冲区读取之前缓冲区里必须有数,即任意时刻运算操作的执行次数必须小于等于读取操作的执行次数。同时应该保证两个读线程和两个运算线程两两互斥。由于以上分析,使用了四个信号量sem1,sem2,sem3和sem4。sem1保证线程1和线程2互斥,sem2保证线程3和线程4互斥,sem3保证线程3和线程4互斥,sem4保证线程4和线程1互斥。即这四个信号量使四个线程循环进行,从而保证了运行结果的正确性。 源代码及注释: #include #include #include #define NUM 200

linux网络操作系统和实训课后习题答案解析

练习题 一、选择题 1. Linux 最早是由计算机爱好者 B 开发的。 A. Richard Petersen B. Linus Torvalds C. Rob Pick D. Linux Sarwar 2. 下列 C 是自由软件。 A. Windows XP B. UNIX C. Linux D. Windows 2000 3. 下列 B 不是Linux 的特点。 A. 多任务 B. 单用户 C. 设备独立性 D. 开放性 4. Linux 的内核版本2.3.20 是 A 的版本。 A. 不稳定 B. 稳定的 C. 第三次修订 D. 第二次修订 二、填空题 1. GUN 的含义是:GNU's Not UNIX。 2. Linux 一般有3 个主要部分:内核(kernel)、命令解释层(Shell 或其他操作环境)、 实用工具。 三、简答题(略) 1. 简述Red Hat Linux 系统的特点。 2. 简述一些较为知名的Linux 发行版本。 练习题 一、选择题 1. Linux 安装过程中的硬盘分区工具是 D 。 A. PQmagic B. FDISK C. FIPS D. Disk Druid 2. Linux 的根分区系统类型是 C 。 A. FATl6 B. FAT32 C. ext3 D. NTFS 二、填空题 1. 安装Linux 最少需要两个分区,分别是 swap 交换分区和/(根)分区。 2. Linux 默认的系统管理员账号是 root 。 3. X-Window System 由三部分构成:X Server、X Client 和通信通道。 三、简答题(略) 1. Linux 有哪些安装方式 2. 安装Red Hat Linux 系统要做哪些准备工作 3. 安装Red Hat Linux 系统的基本磁盘分区有哪些 4. Red Hat Linux 系统支持的文件类型有哪些 练习题 一、选择题 1. C 命令能用来查找在文件TESTFILE 中包含四个字符的行 A. grep’’TESTFILE B. grep’….’TESTFILE C. grep’^$’TESTFILE D. grep’^….$’TESTFILE 2. B 命令用来显示/home 及其子目录下的文件名。 A. ls -a /home B. ls -R /home C. ls -l /home D. ls -d /home 3. 如果忘记了ls 命令的用法,可以采用 C 命令获得帮助 A. ls B. help ls C. man ls D. get ls 4. 查看系统当中所有进程的命令是 D 。 A. ps all B. ps aix C. ps auf D. ps aux

四种进程或线程同步互斥的控制方法

四种进程或线程同步互斥的控制方法 1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 3、信号量:为控制一个具有有限数量用户资源而设计。 4、事件:用来通知线程有一些事件已发生,从而启动后继任务的开始。 一临界区 临界区的使用在线程同步中应该算是比较简单,说它简单还是说它同后面讲到的其它方法相比更容易理解。举个简单的例子:比如说有一个全局变量(公共资源)两个线程都会对它进行写操作和读操作,如果我们在这里不加以控制,会产生意想不到的结果。假设线程A 正在把全局变量加1然后打印在屏幕上,但是这时切换到线程B,线程B又把全局变量加1然后又切换到线程A,这时候线程A打印的结果就不是程序想要的结果,也就产生了错误。解决的办法就是设置一个区域,让线程A在操纵全局变量的时候进行加锁,线程B如果想操纵这个全局变量就要等待线程A释放这个锁,这个也就是临界区的概念。 二互斥体 windows api中提供了一个互斥体,功能上要比临界区强大。也许你要问,这个东东和临界区有什么区别,为什么强大?它们有以下几点不一致: 1.critical section是局部对象,而mutex是核心对象。因此像waitforsingleobject是不可以等待临界区的。 2.critical section是快速高效的,而mutex同其相比要慢很多 3.critical section使用围是单一进程中的各个线程,而mutex由于可以有一个名字,因此它是可以应用于不同的进程,当然也可以应用于同一个进程中的不同线程。 4.critical section 无法检测到是否被某一个线程释放,而mutex在某一个线程结束之后会产生一个abandoned的信息。同时mutex只能被拥有它的线程释放。下面举两个应用mutex 的例子,一个是程序只能运行一个实例,也就是说同一个程序如果已经运行了,就不能再运行了;另一个是关于非常经典的哲学家吃饭问题的例子。 三事件 事件对象的特点是它可以应用在重叠I/O(overlapped I/0)上,比如说socket编程中有两种模型,一种是重叠I/0,一种是完成端口都是可以使用事件同步。它也是核心对象,因此可以被waitforsingleobje这些函数等待;事件可以有名字,因此可以被其他进程开启。 四信号量 semaphore的概念理解起来可能要比mutex还难,我先简单说一下创建信号量的函数,因为我在开始使用的时候没有很快弄清楚,可能现在还有理解不对的地方,如果有错误还是请大侠多多指教。 CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD LONG lInitialCount, // initial count LONG lMaximumCount, // maximum count LPCTSTR lpName // object name )

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

操作系统实验报告 课程名称操作系统实验名称进程(线程)的同步与互斥成绩 学生姓名作业君专业软件工程班级、学号 同组者姓名无实验日期2020 一、实验题目:进程(线程)的同步与互斥 二、实验目的: 自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。1.掌握基本的同步与互斥算法,理解生产者消费者模型。 2.学习使用Windows中基本的同步对象,掌握相关API的使用方法。 3.了解Windows中多线程的并发执行机制,实现进程的同步与互斥 三、实验内容与要求: 1.实验内容 以生产者/消费者模型为依据,在Windows 环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2.实验要求 学习并理解生产者/消费者模型及其同步/互斥规则; 学习了解Windows同步对象及其特性; 熟悉实验环境,掌握相关API的使用方法; 设计程序,实现生产者/消费者进程(线程)的同步与互斥; 四、算法描述(含数据结构定义)或流程图 #include #include #include #include #include #include using namespace std;

#define MAX_THREAD_NUM 64 //最大线程数 #define INTE_PER_SEC 1000 //延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10; //缓冲区长度 int ProductID = 0; //产品号 int ConsumeID = 0; //将被消耗的产品号 int in = 0; //产品进缓冲区时的缓冲区下标 int out = 0; //产品出缓冲区时的缓冲区下标 bool running = true; //判断程序能否继续执行的逻辑值 int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列 HANDLE g_hMutex; //公有信号量,用于线程间的互斥HANDLE g_hFullSemaphore; //生产者的私有信号量,当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore; //消费者的私有信号量,当缓冲区空时迫使消费者等待 //定义一个结构体用于存储线程的信息 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);

实验1编程实现进程(线程)同步和互斥

实验1编程实现进程(线程)同步和互斥 一、实验目的 ①通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与 互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥 ②等有关的内容。 ③了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。 ④学习使用Windows2000/XP中基本的同步对象,掌握相应的 ⑤API函数。 ⑥掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。 ⑦掌握多道程序设计的基本理论、方法和技术,培养学生多道程序设计的能 力。 二、实验内容 在Windows XP、Windows 2000等操作系统下,使用的VC、VB、java或C 等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。 三、实验要求 ①经调试后程序能够正常运行。 ②采用多进程或多线程方式运行,体现了进程(线程)同步和互斥的关系。 ③程序界面美观。 四、实验步骤、过程 让写者与读者、读者与读者之间互斥的访问同一数据集,在无写者进程到来时各读者可同时的访问数据集,在读者和写者同时等待时写者优先唤醒。设置两个全局变量readcount 和writecount来记录读者与写者的数目,设置了3个信号量。h_mutex1表示互斥对象对阻塞在read这一个过程实现互斥,h_mutex2实现全局变量readcount操作上的互斥,h_mutex3实现对全局变量writecount的互斥访问。设置了两个临界区,为了实现写者优先,用了临界区read。数据结构:(1)用了两个临界区(2)自定义结构ThreadInfo记录一条线程信息,多个线程对应一个ThreadInfo数组。(3)设置了互斥量h_mutex1,实现了互斥对象对阻

多线程同步方法及比较

多线程同步方法及比较 多线程同步方法: 1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数 据访问。. 2.互斥量:为协调一起对一个共享资源的单独访问而设计的。. 3.信号量:为控制一个具备有限数量用户资源而设计。. 4.事件:用来通知线程有一些事件已发生,从而启动后继任务的开始。 临界区(Critical Section).. 确保在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。假如有多个线程试图同时访问临界区,那么在有一个线程进入后其他任何试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程能够继续抢占,并以此达到用原子方式操作共享资源的目的。 临界区包含两个操作原语: EnterCriticalSection()进入临界区 LeaveCriticalSection()离开临界区。 EnterCriticalSection()语句执行后代码将进入临界区以后无论发生什么,必须确保和之匹配的LeaveCriticalSection()都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。 MFC为临界区提供有一个CCriticalSection类,使用该类进行线程同步处理是很简单的。只需在线程函数中用CCriticalSection类成员函数Lock()和UnLock()标定出被保护代码片段即可。Lock()后代码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。. ------------------------------------------------

Windows下进程同步与互斥

实验进程同步与互斥 一、实验目的 1.掌握基本的同步与互斥算法,理解生产者消费者模型。 2.学习使用Windows 2000/XP中基本的同步对象,掌握相关API的使用方法。 3.了解Windows 2000/XP中多线程的并发执行机制,实现进程的同步与互斥。 二、实验内容及要求 1.实验内容 以生产者/消费者模型为依据,在Windows 2000环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2.实验要求 ●学习并理解生产者/消费者模型及其同步/互斥规则; ●学习了解Windows同步对象及其特性; ●熟悉实验环境,掌握相关API的使用方法; ●设计程序,实现生产者/消费者进程(线程)的同步与互斥; ●提交实验报告。 三、相关知识介绍 1.同步对象 同步对象是指Windows中用于实现同步与互斥的实体,包括信号量(Semaphore)、互斥量(Mutex)、临界区(Critical Section)和事件(Events)等。本实验中使用到信号量、互斥量和临界区三个同步对象。 同步对象的使用步骤: ●创建/初始化同步对象。 ●请求同步对象,进入临界区(互斥量上锁)。 ●释放同步对象(互斥量解锁)。 这些对象在一个线程中创建,在其他线程中都可以使用,实现同步与互斥。 2.相关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,

Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。 一个进程可以有很多线程,每条线程并行执行不同的任务。 线程可以提高应用程序在多核环境下处理诸如文件I/O或者socket I/O等会产生堵塞的情况的表现性能。在Unix系统中,一个进程包含很多东西,包括可执行程序以及一大堆的诸如文件描述符地址空间等资源。在很多情况下,完成相关任务的不同代码间需要交换数据。如果采用多进程的方式,那么通信就需要在用户空间和内核空间进行频繁的切换,开销很大。但是如果使用多线程的方式,因为可以使用共享的全局变量,所以线程间的通信(数据交换)变得非常高效。 Hello World(线程创建、结束、等待) 创建线程 pthread_create 线程创建函数包含四个变量,分别为: 1. 一个线程变量名,被创建线程的标识 2. 线程的属性指针,缺省为NULL即可 3. 被创建线程的程序代码 4. 程序代码的参数 For example: - pthread_t thrd1? - pthread_attr_t attr? - void thread_function(void argument)? - char *some_argument? pthread_create(&thrd1, NULL, (void *)&thread_function, (void *) &some_argument); 结束线程 pthread_exit 线程结束调用实例:pthread_exit(void *retval); //retval用于存放线程结束的退出状态 线程等待 pthread_join pthread_create调用成功以后,新线程和老线程谁先执行,谁后执行用户是不知道的,这一块取决与操作系统对线程的调度,如果我们需要等待指定线程结束,需要使用pthread_join函数,这个函数实际上类似与多进程编程中的waitpid。 举个例子,以下假设 A 线程调用 pthread_join 试图去操作B线程,该函数将A线程阻塞,直到B线程退出,当B线程退出以后,A线程会收集B线程的返回码。 该函数包含两个参数:pthread_t th //th是要等待结束的线程的标识 void **thread_return //指针thread_return指向的位置存放的是终止线程的返回状态。 调用实例:pthread_join(thrd1, NULL); example1: 1 /************************************************************************* 2 > F i l e N a m e: t h r e a d_h e l l o_w o r l d.c 3 > A u t h o r: c o u l d t t(f y b y) 4 > M a i l: f u y u n b i y i@g m a i l.c o m 5 > C r e a t e d T i m e: 2013年12月14日 星期六 11时48分50秒 6 ************************************************************************/ 7 8 #i n c l u d e 9 #i n c l u d e 10 #i n c l u d e

11 12 v o i d p r i n t_m e s s a g e_f u n c t i o n (v o i d *p t r)? 13 14 i n t m a i n() 15 { 16 i n t t m p1, t m p2?

同步与互斥

习题解答: ?何谓与时间有关的错误? 举例说明之。 答:并发进程的执行实际上是进程活动的某种交叉,某些交叉次序可能得到错误结果。由于具体交叉的形成与进程的推进速度有关,而速度是时间的函数,因而将这种错误称为与时间有关的错误。 例如,两个并发进程的程序如下: int n=0; main( ){ 创建进程A; 创建进程B; }; A( ){ while(1){ n++; } }; B( ){ while(1){ 睡眠一段时间;printf(“%d”,n); n=0; } }; 假设进程A被部署在公园入口的终端上,用来记录一段时间内进入公园的人数,进程B被部署在公园的控制中心,用来输出一段时间内进入公园的总人数。进程A和进程B共享全局变量n,n表示记录下的人数。如果在进程B执行完打印语句后被进程A打断,进程A执行了若干次变量自增语句,之后进程B接着执行清0语句,那么进程A对n的累加丢失了,相当于进程B被打断的这段时间内进入公园的人没有被记录下来。发生与时间有关的错误。 ?有人说,假设两个进程之间没有共享内存,则二者之间没有公共变量,这种说法准确吗? 说明原因。 答:如果只从用户空间考虑,这种说法是正确的。但从操作系统的角度来说并不准确。两个没有公共内存的用户进程可能同时(宏观)进入操作系统,并访问操作系统空间中的公共变

量。 ?何谓忙式等待? 是否还有其它方式的等待? 比较它们之间的联系和差别。 答:不进入等待状态的等待称为忙式等待。另一种等待方式是阻塞式等待,进程得不到共享资源时将进入阻塞状态,让出CPU给其他进程使用。忙等待和阻塞式等待的相同之处在于进程都不具备继续向前推进的条件,不同之处在于处于忙等待的进程不主动放弃CPU,尽管CPU 可能被剥夺,因而是低效的;而处于阻塞状态的进程主动放弃CPU,因而是高效的。 ?下列进程互斥方法哪些存在忙式等待问题? (1)软件: 面包店算法(2) 硬件: TS指令(3) 关中断指令 答:(1)、(2)存在忙等待问题。 ?为何开关中断进程互斥方法仅在单CPU系统中是有效的? 答:关中断方法不适用于多CPU系统,因为关中断只能保证CPU不由一个进程切换到另外一个进程,从而防止多个进程并发地进入公共临界区域。但即使关中断后,不同进程仍可以在不同CPU上并行执行关于同一组共享变量的临界区代码. ?在多处理机系统中,软件互斥方法是否有效?为什么? 答:依然有效。多处理机并行与单处理并发之间的差别在于程序交叉的粒度,单处理机机环境中进程交叉发生在指令之间,多处理机环境中进程交叉发生在指令周期之间。由于纯软件互斥算法并不依赖特殊的硬件指令(如test_and_set),指令之间的交叉与指令周期之间的交叉结果相同。 ?试分析临界区域的大小与系统并发性之间的关系。 答:关于同一组变量的临界区域是不能并发执行的代码,临界区越大,并发性越差,因而编写并发程序应尽量缩小临界区域范围。 ?设CR1是关于一组共享变量SV1的临界区域,CR2是关于另外一组共享变量SV2的临

Linux系统管理与网络管理附答案

Linux系统管理与网络管理 一、选择题 1、Linux系统是一个(D )操作系统。 A、单用户、单任务 B、单用户、多任务 C、多用户、单任务 D、多用户、多任务 2、Redhat Linux 系统中用户默认的shell是(A )。 A、bsh B、ksh C、csh D、sh 3、对于文件扩展名的tar.bzz的源代码发布的软件安装解压和解压缩,正确的tar 命令参数是( C )。 A、tarzxvf文件名 B、tarxvf文件名 C、tarzxvf文件名 D、tarjxvf文件名 4、/dev/sdc6分区表示(D )。 A、第2块IDE硬盘的第六个分区是逻辑分区 B、第3块IDE硬盘的第六个分区是逻辑分区 C、第3块SCSI硬盘的第六个分区是逻辑分区 D、第3块SCSI硬盘的第二个分区是逻辑分区 5、Linux文件系统的文件都按其作用分门类别地放在相关的目录中,对于外部设备文件一般应将其放在( C )目录中。 A、/bin B、/etc C、/dev D、/lib 6、Linux的根分区系统类型是(C )。 A、FAT16 B、FAT32 C、ext3 D、NTFS 7、Linux的内核版本2.5.20是(B )的版本。 A、稳定 B、不稳定 C、第五次修订 D、第二次 8、启动运行级别3表示(D )。 A、关闭系统 B、单用户 C、无网络功能的多用户模式 D、完整的多用户模式 9、超级用户的UID是(A )。 A、0 B、1 C、500 D、10 10、改变文件或目录的访问权限使用(A )命令。 A、chmod B、chown C、usermod D、userdel 11、用于保护用户账号信息的文件是(B ) A、/etc/group B、/etc/passwd C、/etc/gshadow D、/etc/inittab 12、Linux操作系统中,管道符用(C )表示。 A、~ B、$ C、| D、# 13、要将用户添加到指定组群中,应该使用的命令是(A )。 A、groupadd B、groupmod C、gpasswd D、groupuser 14、以下哪个命令可以将普通用户转换成超级用户(D )。 A、super B、passwd C、tar D、su 15、用“useraddjohn”命令添加一个用户,这个用户的主目录是(A )。 A、/home/john B、/bin/john C、/var/john D、/etc/john 16、下列哪一个指令可以显示目前的路径(C )。 A、show B、cd C、pwd D、more 17、下列哪一个指令可以用来显示档案的内容( D )。

同步和互斥的区别_

同步和互斥的区别

信号量互斥量条件变量 同步和互斥 一、信号量:用于进程间通信(linux中用于线程) 独立于进程在两个进程中都要初始化,若一个已创建,则另一个获取可以执行多次v操作,然后再执行p操作 信号量的一些概念: 以下是信号灯(量)的一些概念: 信号灯与互斥锁和条件变量的主要不同在于”灯”的概念,灯亮则意味着资源可用,灯灭则意味着不可用。如果说后两中同步方式侧重于”等待”操作,即资源不可用的话,信号灯机制则侧重于点灯,即告知资源可用;没有等待线程的解锁或激发条件都是没有意义的,而没有等待灯亮的线程的点灯操作则有效,且能保持灯亮状态。当然,这样的操作原语也意味着更多的开销。 信号灯的应用除了灯亮/灯灭这种二元灯以外,也可以采用大于1的灯数,以表示资源数大于1,这时可以称之为多元灯。 二、互斥量:(用于在线程间的通信) 1、在一个进程中创建 三、信号量与互斥量的区别 1. 互斥量用于线程的互斥,信号量用于线程的同步。 这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源 以上区别是主要想记住的。 note:信号量可以用来实现互斥量的功能 2. 互斥量值只能为0/1,信号量值可以为非负整数。 也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。3、互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。 4、作用域 信号量: 进程间或线程间(linux仅线程间) 互斥锁: 线程间 5、上锁时 信号量: 只要信号量的value大于0,其他线程就可以sem_wait(p操作-1)成功,成功后信号量的value减一。若value值不大于0,则

实验一 进程同步与互斥

实验一进程同步与互斥 一、实验目的 1.掌握基本的同步与互斥算法,理解生产者消费者模型。 2.学习使用Windows 2000/XP中基本的同步对象,掌握相关API的使用方法。 3.了解Windows 2000/XP中多线程的并发执行机制,实现进程的同步与互斥。 二、实验内容及要求 1.实验内容 以生产者/消费者模型为依据,在Windows 2000环境下创建一个控制台进程,在该进程 中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2.实验要求 , 学习并理解生产者/消费者模型及其同步/互斥规则; , 学习了解Windows同步对象及其特性; , 熟悉实验环境,掌握相关API的使用方法; , 设计程序,实现生产者/消费者进程(线程)的同步与互斥; , 提交实验报告。 三、相关知识介绍 1.同步对象 同步对象是指Windows中用于实现同步与互斥的实体,包括信号量(Semaphore)、互斥量(Mutex)、临界区(Critical Section)和事件(Events)等。本实验中使用到信号量、互斥量和临

界区三个同步对象。 同步对象的使用步骤: , 创建/初始化同步对象。 , 请求同步对象,进入临界区(互斥量上锁)。 , 释放同步对象(互斥量解锁)。 这些对象在一个线程中创建,在其他线程中都可以使用,实现同步与互斥。 2.相关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, DWORD dwCreationFlags, Lpdword lpThread ); , 参数说明 lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。

相关文档 最新文档