实验1编程实现进程(线程)同步和互斥
实验、进程的同步与互斥——生产者消费者

实验、进程的同步与互斥——⽣产者消费者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编程实现进程(线程)同步和互斥

实验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,实现了互斥对象对阻塞read这一过程,h_mutex2实现对readcount操作的互斥,h_mutex3实现对writecount的互斥访问。
操作系统实验实验报告

操作系统实验实验报告一、实验目的操作系统是计算机系统中最为关键的核心软件,它管理着计算机的硬件资源和软件资源,为用户提供了一个方便、高效、稳定的工作环境。
本次操作系统实验的目的在于通过实际操作和实践,深入理解操作系统的基本原理和核心概念,掌握操作系统的基本功能和操作方法,提高对操作系统的认识和应用能力。
二、实验环境本次实验使用的操作系统为 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 等进行文件的创建、读取和写入操作。
进程的同步与互斥实验报告

进程的同步与互斥实验报告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. 理解线程的概念和并发编程的基本原理。
2. 掌握线程的创建、同步和通信方法。
3. 通过实验加深对线程并发编程的理解,提高编程能力。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C++三、实验内容本次实验主要涉及以下内容:1. 线程的创建与销毁2. 线程的同步与互斥3. 线程的通信4. 线程池的使用四、实验步骤1. 线程的创建与销毁(1)创建线程:使用C++11标准中的`std::thread`类创建线程。
```cpp#include <iostream>#include <thread>void threadFunction() {std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;}int main() {std::thread t1(threadFunction);std::thread t2(threadFunction);t1.join(); // 等待线程t1结束t2.join(); // 等待线程t2结束return 0;}```(2)销毁线程:线程会在任务执行完毕后自动销毁,无需手动销毁。
2. 线程的同步与互斥(1)互斥锁:使用`std::mutex`类实现线程间的互斥。
```cpp#include <iostream>#include <thread>#include <mutex>std::mutex mtx;void threadFunction() {mtx.lock();std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;mtx.unlock();}int main() {std::thread t1(threadFunction);t1.join();t2.join();return 0;}```(2)条件变量:使用`std::condition_variable`类实现线程间的条件同步。
进程同步实验报告

一、实验目的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)通过实验验证了进程同步机制的有效性。
五、实验总结本次实验通过使用信号量和互斥锁,实现了进程同步。
实验结果表明,信号量和互斥锁能够有效地保证进程按照预期顺序执行,避免数据不一致和死锁等问题。
操作系统实验进程同步与互斥

操作系统实验进程同步与互斥操作系统实验进程同步与互斥实验目的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. 互斥锁(Mutex)互斥锁是一种最常用的同步机制,通过对一些代码块或函数的访问加上互斥锁的操作,可以保证只有一个线程能够执行该代码块或函数。
当一些线程获得互斥锁时,其他线程在获得该锁之前会被阻塞。
2. 信号量(Semaphore)信号量是一种更为复杂的同步机制,用于实现一些资源的访问控制。
一个信号量有一个整型值和两个原子操作:P和V。
P操作(也称为wait或down)会使信号量的值减1,如果值小于0,当前线程或进程就会被阻塞。
V操作(也称为signal或up)会使信号量的值加1,如果值小于等于0,就会唤醒等待的线程或进程。
信号量可以用于解决生产者-消费者问题、读者-写者问题等并发编程中的资源竞争问题。
3. 条件变量(Condition Variable)条件变量是一种同步机制,用于在多个线程或进程之间同步共享资源的状态。
条件变量对应一个条件,并提供了等待和通知的机制。
等待操作可以使一个线程或进程等待一些条件成立,直到其他线程或进程通知条件变量,使得等待的线程或进程被唤醒。
通知操作可以使等待中的线程或进程被唤醒,继续执行。
条件变量常和互斥锁一起使用,互斥锁用于保护共享资源,条件变量用于同步共享资源的状态。
三、实现互斥的方法1. Peterson算法Peterson算法是一种经典的软件方法,用于解决两个进程之间的互斥访问问题。
该算法使用了两个布尔型变量flag和turn,通过交替使用这两个变量,实现了两个进程之间的互斥。
2. 印章(Semaphores)信号量也可以用于实现互斥操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验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,实现了互斥对象对阻塞read这一过程,h_mutex2实现对readcount操作的互斥,h_mutex3实现对writecount的互斥访问。
流程:(1)主函数(2)临界区初始化(3)提取线程相关信息(4)完成线程相关信号量的初始化(5)创建读者与写者线程(6)等待所有线程结束(7)程序结束(8)读者(9)提取本线程信息(10)等待,提出读请求(11)进入临界区(12)进行读操作,并判读是否读完(15)退出临界区,读操作完成(16)如果readcount=0,则唤醒写者(17)写者(18)提取本线程信息(19)等待,发出写请求(20)进入临界区(21)进行写操作,并判断是否写完(22)退出临界区,写操作完成(23)如果writecount=0,则唤醒读者代码:#include<windows.h>#include<fstream.h>#include<stdio.h>#include<string>#include<conio.h>#define INTE_PER_SEC 1000//每秒时钟中断的数目#define MAX_THREAD_NUM 64//最大线程数int readcount=0;//读者数目int writecount=0;//写者数目CRITICAL_SECTION cs_write;CRITICAL_SECTION cs_read;void Writer(void *p);void Reader(void *p);//定义记录在测试文件中的线程参数数据结构struct ThreadInfo{ int serial;char entity;double delay;double persist;};//全局变量定义//临界区对象的声明,用于管理缓冲区的互斥访问int m;HANDLE h_Thread[MAX_THREAD_NUM]; //存储线程句柄的数组ThreadInfo Thread_Info[MAX_THREAD_NUM]; //线程信息数组HANDLE h_mutex1; //互斥对象对阻塞在read这一个过程实现互斥HANDLE h_mutex2; //全局变量readcount实现操作上的互斥DWORD n_Thread=0; //实际线程数目HANDLE h_mutex3; //对全局变量writecount的互斥访问int main(void){DWORD wait_for_all;FILE *inFile; //ifstream inFile;int i,j;InitializeCriticalSection(&cs_write); //初始化临界区InitializeCriticalSection(&cs_read);//打开输入文件,提取线程信息inFile=fopen("test.txt","r");fscanf(inFile, "%d",&m);//提取各线程信息到相应的数据结构中while(!feof(inFile)){fscanf(inFile,"%d",&Thread_Info[n_Thread].serial);fscanf(inFile,"\t%c",&Thread_Info[n_Thread].entity);fscanf(inFile,"%lf",&Thread_Info[n_Thread].delay);fscanf(inFile,"%lf",&Thread_Info[n_Thread].persist);n_Thread++;}//回显获得的线程信息,便于确认正确性for(j=0;j<(int)n_Thread;j++){int Temp_serial=Thread_Info[j].serial;char Temp_entity=Thread_Info[j].entity;double Temp_delay=Thread_Info[j].delay;double Temp_persist=Thread_Info[j].persist;printf(" \n thread%2d %c %lf %lf",Temp_serial,Temp_entity,Temp_delay,Temp_persist);printf("\n");}printf("\n\n");//创建模拟过程中必要的信号量h_mutex1=CreateMutex(NULL,FALSE,"mutex_for_readcount");h_mutex2=CreateMutex(NULL,FALSE,"mutex_for_readwait");h_mutex3=CreateMutex(NULL,FALSE,"mutex_for_writecount");//创建读者和写者线程for(i=0;i<(int)(n_Thread);i++){if(Thread_Info[i].entity=='R'||Thread_Info[i].entity =='r'){h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Reader),&(Thread_Info[i]),0,N ULL);}else{h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Writer),&(Thread_Info[i]),0,N ULL);}}//主程序等待各个线程的动作结束wait_for_all=WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf(" \n \nALL READER and WRITER have finished their work, \n");printf("Press any key to quit!\n");return 0;}//读者线程void Reader(void *p){//局部变量声明DWORD wait_for_semaphore,wait_for_mutex;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);Sleep(m_delay);printf("Reader thread %d sends readering require.\n",m_serial);wait_for_semaphore=WaitForSingleObject(h_mutex1,-1);EnterCriticalSection(&cs_read);wait_for_mutex=WaitForSingleObject(h_mutex2,-1);readcount++;if(readcount==1){// 如果是第1个读者,等待写者写完EnterCriticalSection(&cs_write);}ReleaseMutex(h_mutex2);// 释放互斥信号 Mutex2//让其他读者进去临界区LeaveCriticalSection(&cs_read);ReleaseMutex(h_mutex1);//读文件printf("Reader thread %d begins to read file.\n",m_serial);Sleep(m_persist);//退出线程printf("Reader thread %d finished reading file.\n",m_serial);//阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥wait_for_mutex=WaitForSingleObject(h_mutex2,-1);readcount--;if(readcount==0){//最后一个读者,唤醒写者LeaveCriticalSection(&cs_write);}ReleaseMutex(h_mutex2); //释放互斥信号}//写者线程void Writer(void *p){ DWORD wait_for_mutex3; //互斥变量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);Sleep(m_delay); //延迟等待printf("Writer thread %d sents the writing require.\n",m_serial);wait_for_mutex3=WaitForSingleObject(h_mutex3,-1);writecount++; //修改写者数目if(writecount==1){EnterCriticalSection(&cs_read);}ReleaseMutex(h_mutex3);EnterCriticalSection(&cs_write);printf("Writer thread %d begins to write to the file.\n",m_serial); Sleep(m_persist);printf("Writer thread %d finished writing to the file.\n",m_serial); LeaveCriticalSection(&cs_write);wait_for_mutex3=WaitForSingleObject(h_mutex3,-1);writecount--;if(writecount==0){LeaveCriticalSection(&cs_read);}ReleaseMutex(h_mutex3);}五、实验结果或总结1、测试文件1 R2 32 R3 53 W 1 14 R 10 55 R 12 46 W 9 87 R 13 68 W 12 59 R 20 1010 W 21 20 2、测试结果3、测试结果分析由测试结果可知,线程3最早发出操作请求,并执行,开始执行后线程1发出读请求,3完成操作,1开始读操作,2发出读请求,2开始读操作,1、2完成读操作,实现了读者同步,6发出写请求,6开始写操作,4、5发出读请求,8发出写请求,7发出读请求,形成2个等待队列,一个是读这等待队列有线程4、5、7,一个是写者等待队列8,当6完成操作时,优先唤醒写者线程8,实现了写者优先,写者写完了再唤醒读者等待队列,实现了多个读者同步。