实验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编程实现进程(线程)同步和互斥

实验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编程实现进程同步和互斥

1编程实现进程同步和互斥

1编程实现进程同步和互斥进程同步和互斥是操作系统中非常重要的概念,用于确保多个进程或线程之间能够按照一定的顺序进行并发执行,避免数据竞争和资源冲突。

1.进程同步:进程同步是指多个进程或线程按照一定的顺序执行,以避免数据竞争和资源冲突。

1.1 互斥量(Mutex):互斥量是一种最常见的进程同步机制。

它基于二进制信号量的原理,保证在同一时刻只能有一个进程访问共享资源。

在访问共享资源之前,进程需要先请求互斥量,如果互斥量被锁定,则进程进入等待状态,直到互斥量被释放。

互斥量的基本操作包括锁定和释放。

1.2 信号量(Semaphore):信号量是另一种常见的进程同步机制。

它是一个整型变量,用于控制多个进程对共享资源的访问。

在访问共享资源之前,进程需要先检查信号量的值。

如果信号量的值大于0,则进程可以继续执行。

如果信号量的值等于0,则进程进入等待状态,直到其他进程释放信号量。

信号量的基本操作包括加1和减11.3 条件变量(Condition Variable):条件变量是一种进程同步的机制,用于在多个进程之间传递信号以实现其中一种特定的行为。

在进程访问共享资源时,如果条件不满足,则进程进入等待状态。

当条件满足时,其他进程通过发送信号给被阻塞的进程来唤醒它们。

2.进程互斥:进程互斥是指多个进程或线程之间避免并发执行,以防止数据竞争和资源冲突。

2.1 互斥锁(Mutual Exclusion Lock):互斥锁是一种用于保护共享资源的机制。

在进程访问共享资源之前,需要先获取互斥锁。

如果互斥锁已经被其他进程持有,则当前进程会被阻塞,直到其他进程释放互斥锁。

一旦当前进程获得互斥锁,就可以访问共享资源,访问完成后,需要释放互斥锁。

2.2 读写锁(Read-Write Lock):读写锁是一种更为复杂的进程互斥机制。

它允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。

在写入共享资源之前,需要获取写锁。

如果写锁已经被其他线程持有,则写操作被阻塞。

实验一进程的同步与互斥

实验一进程的同步与互斥

实验一进程的同步与互斥一、实验目的(1)加深对进程概念的理解,明确进程和程序的区别。

(2)进一步认识并发执行的实质。

(3)分析进程竞争资源现象,学习解决进程互斥的法。

(4)了解Windows对进程管理的支持。

二、实验类型观察/分析型。

三、预习内容预习进程管理有关理论和VC++对进程管理的支持, 包括进程的基本操作和经典的进程同步与互斥问题。

四、实验要求本实验通过学习和分析三个简单的Windows 线程编程编写一个简单的生产者/消费者问题实例程序。

利用(1)和(2)中的Windows 进程和线程创建法实现一个简单的读者,写者程序,读者将1~10 十个数字依次填入临界资源区gData,当且仅当gData 被读者消费后,写者才可以写入下一个数。

五、实验代码#include "windows.h"#include <conio.h>#include <stdio.h>#include <math.h>const int writerNum = 1;const int readerNum = 1;int gData = 0;bool continu = true;HANDLE hmutex;HANDLE hfullsemaphore;HANDLE hemptysemaphore;DWORD WINAPI reader(LPVOID lppara){while(continu){WaitForSingleObject(hemptysemaphore,INFINITE);WaitForSingleObject(hmutex,INFINITE);if(gData >= 11){continu = false;break;}Sleep(100);printf("readers gets data:%d\n", gData);printf("\n");ReleaseMutex(hmutex);ReleaseSemaphore(hfullsemaphore,1,NULL);}return NULL;}DWORD WINAPI writer(LPVOID lppara){while(continu){WaitForSingleObject(hfullsemaphore,INFINITE);WaitForSingleObject(hmutex,INFINITE);if(gData >= 10){continu = false;break;}Sleep(100);gData++;printf("writer gets data:%d\n", gData);printf("\n");ReleaseMutex(hmutex);ReleaseSemaphore(hemptysemaphore,1,NULL);}return NULL;}int main(){hmutex = CreateMutex(NULL,false,NULL);hfullsemaphore = CreateSemaphore(NULL,1,1,NULL);hemptysemaphore = CreateSemaphore(NULL,0,1,NULL);DWORD readerdata;DWORD writerdata;for (int i=0;i<writerNum;i++){if(CreateThread(NULL,0,writer,NULL,0,&writerdata)==NULL) return -1;}for (int j=0;j<readerNum;j++){if(CreateThread(NULL,0,reader,NULL,0,&readerdata)==NULL) return -1;}printf("Program ends successfully\n");return 0;}。

进程管理实验报告代码

进程管理实验报告代码

一、实验目的1. 理解进程的概念和进程状态转换。

2. 掌握进程同步与互斥的基本方法。

3. 学习使用信号量实现进程同步与互斥。

4. 熟悉进程调度算法。

二、实验环境1. 操作系统:Windows/Linux2. 编程语言:C/C++3. 开发工具:Visual Studio/Code::Blocks三、实验内容1. 进程状态转换2. 进程同步与互斥3. 信号量实现进程同步与互斥4. 进程调度算法四、实验步骤1. 进程状态转换```c#include <stdio.h>#include <unistd.h>void print_status(int state) {switch (state) {case 1: printf("创建状态\n"); break; case 2: printf("就绪状态\n"); break;case 3: printf("运行状态\n"); break; case 4: printf("阻塞状态\n"); break; case 5: printf("终止状态\n"); break; default: printf("未知状态\n"); break; }}int main() {int state = 1;print_status(state);sleep(1);state = 2;print_status(state);sleep(1);state = 3;print_status(state);sleep(1);state = 4;print_status(state);sleep(1);state = 5;print_status(state);return 0;}```2. 进程同步与互斥```c#include <stdio.h>#include <pthread.h>pthread_mutex_t lock;void thread_func(void arg) {pthread_mutex_lock(&lock);printf("线程 %d 进入临界区\n", (int )arg);sleep(2);printf("线程 %d 离开临界区\n", (int )arg);pthread_mutex_unlock(&lock);return NULL;}int main() {pthread_t tid1, tid2;int arg1 = 1, arg2 = 2;pthread_mutex_init(&lock, NULL);pthread_create(&tid1, NULL, thread_func, &arg1); pthread_create(&tid2, NULL, thread_func, &arg2); pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_mutex_destroy(&lock);return 0;}```3. 信号量实现进程同步与互斥```c#include <stdio.h>#include <pthread.h>#include <semaphore.h>sem_t sem;void thread_func(void arg) {sem_wait(&sem);printf("线程 %d 进入临界区\n", (int )arg);sleep(2);printf("线程 %d 离开临界区\n", (int )arg);sem_post(&sem);return NULL;}int main() {pthread_t tid1, tid2;int arg1 = 1, arg2 = 2;sem_init(&sem, 0, 1);pthread_create(&tid1, NULL, thread_func, &arg1); pthread_create(&tid2, NULL, thread_func, &arg2);pthread_join(tid1, NULL);pthread_join(tid2, NULL);sem_destroy(&sem);return 0;}```4. 进程调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define MAX_PROCESSES 5typedef struct {int pid;int arrival_time;int burst_time;int wait_time;int turnaround_time;} Process;int compare(const void a, const void b) {Process proc1 = (Process )a;Process proc2 = (Process )b;return proc1->arrival_time - proc2->arrival_time;}void fcfs(Process processes[], int n) {processes[0].wait_time = 0;processes[0].turnaround_time = processes[0].burst_time;for (int i = 1; i < n; i++) {processes[i].wait_time = processes[i - 1].turnaround_time + processes[i].arrival_time - processes[i].burst_time;processes[i].turnaround_time = processes[i].wait_time + processes[i].burst_time;}}int main() {Process processes[MAX_PROCESSES] = {{1, 0, 3, 0, 0},{2, 1, 6, 0, 0},{3, 4, 4, 0, 0},{4, 6, 5, 0, 0},{5, 8, 2, 0, 0}};qsort(processes, MAX_PROCESSES, sizeof(Process), compare);fcfs(processes, MAX_PROCESSES);for (int i = 0; i < MAX_PROCESSES; i++) {printf("PID: %d, Wait Time: %d, Turnaround Time: %d\n", processes[i].pid, processes[i].wait_time, processes[i].turnaround_time);}return 0;}```五、实验结果与分析通过以上实验,我们了解了进程状态转换、进程同步与互斥、信号量实现进程同步与互斥以及进程调度算法。

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

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

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

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

我们将编写两个进程,一个进程负责打印奇数,另一个进程负责打印偶数,两个进程交替打印,要求打印的数字从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,表示可以打印偶数。

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

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

操作系统实验之进程管理实验报告一、实验目的本次操作系统实验的主要目的是深入理解进程管理的概念和原理,通过实际操作和观察,掌握进程的创建、调度、同步与互斥等关键机制。

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

三、实验内容1、进程创建使用系统提供的 API 函数创建新的进程。

观察新进程的资源使用情况和运行状态。

2、进程调度编写程序模拟不同的进程调度算法,如先来先服务(FCFS)、短作业优先(SJF)和时间片轮转(RR)。

比较不同调度算法下的平均周转时间、平均等待时间等性能指标。

3、进程同步与互斥利用信号量、互斥锁等机制实现进程之间的同步与互斥。

设计并发程序,解决生产者消费者问题、读写者问题等经典同步问题。

四、实验步骤1、进程创建实验首先,包含所需的头文件,如`<windowsh>`。

然后,定义创建进程的函数,使用`CreateProcess` 函数创建新进程,并获取进程的相关信息,如进程标识符、线程标识符等。

最后,通过查看任务管理器或其他系统工具,观察新创建进程的资源占用情况。

2、进程调度实验设计不同的调度算法函数,如`FCFSSchedule`、`SJFSchedule` 和`RRSchedule`。

在每个调度算法函数中,模拟进程的到达时间、服务时间等参数,并按照相应的算法进行进程调度。

计算每个进程的周转时间和等待时间,并求出平均周转时间和平均等待时间。

3、进程同步与互斥实验定义信号量或互斥锁变量。

在生产者消费者问题中,生产者在生产产品时获取互斥锁,生产完成后释放互斥锁并通知消费者;消费者在消费产品时获取互斥锁,消费完成后释放互斥锁。

在读写者问题中,读者在读取数据时获取共享锁,读完后释放共享锁;写者在写入数据时获取独占锁,写入完成后释放独占锁。

五、实验结果与分析1、进程创建实验结果成功创建新的进程,并能够获取到进程的相关信息。

进程互斥实验报告

进程互斥实验报告

一、实验目的1. 理解进程互斥的概念和意义。

2. 掌握进程互斥的实现方法。

3. 熟练运用信号量机制解决进程互斥问题。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 进程互斥的概念进程互斥是指两个或多个进程不能同时进入关于同一组共享变量的临界区域。

如果多个进程同时访问临界资源,可能会导致数据不一致或程序错误。

因此,进程互斥是操作系统中的一个重要概念。

2. 进程互斥的实现方法(1)软件方法:通过程序设计实现进程互斥,如使用锁(Lock)机制、信号量(Semaphore)机制等。

(2)硬件方法:利用处理器提供的特殊指令实现进程互斥,如Test-and-Set指令。

3. 信号量机制信号量是一种整数变量,用于实现进程同步和互斥。

信号量有三种操作:P操作(等待)、V操作(信号)和初始化。

(1)P操作:当进程需要访问临界资源时,先执行P操作。

如果信号量的值大于0,则将其减1,进程继续执行;如果信号量的值等于0,则进程进入阻塞状态,等待其他进程释放信号量。

(2)V操作:当进程访问完临界资源后,执行V操作。

如果此时有其他进程因P操作而阻塞,则将其唤醒,继续执行。

(3)初始化:将信号量的值设置为1,表示临界资源可用。

4. 实验步骤(1)创建一个信号量对象。

(2)在访问临界资源前,执行P操作。

(3)访问临界资源。

(4)访问完成后,执行V操作。

(5)重复步骤(2)至(4)。

5. 实验程序以下是一个使用信号量实现进程互斥的示例程序:```cpp#include <iostream>#include <thread>#include <semaphore.h>// 创建信号量sem_t sem;// 访问临界资源的函数void accessResource() {// 执行P操作sem_wait(&sem);// 访问临界资源std::cout << "进程 " << std::this_thread::get_id() << " 正在访问临界资源" << std::endl;// 执行V操作sem_post(&sem);}int main() {// 初始化信号量sem_init(&sem, 0, 1);// 创建多个线程std::thread t1(accessResource);std::thread t2(accessResource);std::thread t3(accessResource);// 等待线程结束t1.join();t2.join();t3.join();// 销毁信号量sem_destroy(&sem);return 0;}```6. 实验结果与分析通过运行实验程序,可以观察到多个线程交替访问临界资源,实现了进程互斥。

线程的同步和互斥问题

线程的同步和互斥问题

实验二线程的同步和互斥问题一.实验内容:编写程序实现并发线程之间的同步和互斥问题。

线程间的互斥:并发执行的线程共享某些类临界资源,对临界资源的访问应当采取互斥的机制。

线程间的同步:并发执行的线程间通常存在相互制约的关系,线程必须遵循一定的规则来执行,同步机制可以协调相互制约的关系。

二.实验目的和要求1)了解进程同步与互斥的概念,掌握编写进程同步、互斥的实例。

2)解决一类典型的进程间同步问题,如生产者-消费者问题,读者-写者问题等。

三.实验方法和步骤1.实验方法掌握同步与互斥的机制,选取合适的问题,给出演示程序的设计思想,包括流程图的形式;选取C、C++、VC、JA V A等计算机语言,编程调试,最终给出运行正确的程序。

2.程序设计(1)线程间互斥:分析问题,创建多个线程,找出临界资源,划出正确的临界区,根据互斥机制的操作模式,编写程序。

互斥机制的操作模式:p(mutex);/*关锁*/临界区的操作;v(mutex);/*开锁*/(2)线程间同步——读者-写者问题示例:在Windows 2000 环境下,创建一个包含n 个线程的控制台进程。

用这n 个线程来表示n个读者或写者。

每个线程按相应测试数据文件的要求,进行读写操作。

请用信号量机制分别实现读者优先和写者优先的读者-写者问题。

读者-写者问题的读写操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许;运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。

测试数据文件格式测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。

每行测试数据包括四个字段,各字段间用空格分隔。

第一字段为一个正整数,表示线程序号。

第二字段表示相应线程角色,R 表示读者是,W 表示写者。

第三字段为一个正数,表示读写操作的开始时间。

实验一、二(OS)

实验一、二(OS)

实验一进程同步和互斥(建议4学时)一、实验目的1.掌握临界资源、临界区概念及并发进程互斥、同步访问原理。

2.学会使用高级语言进行多线程编程的方法。

3.掌握利用VC++或Java语言线程库实现线程的互斥、条件竞争,并编码实现P、V 操作,利用P、V操作实现两个并发线程对有界临界区的同步访问。

4.通过该实验,学生可在源代码级完成进程同步互斥方案的分析、功能设计、编程实现,控制进程间的同步、互斥关系。

二、实验要求1.知识基础:学生应在完成进程和线程及调度等章节的学习后进行。

2.开发环境与工具:硬件平台——个人计算机。

软件平台-Windows操作系统,vc++语言或Java语言开发环境。

3.运用高级语言VC++或Java语言线程库及多线程编程技术进行设计实现。

三、实验内容1.实现临界资源、临界区、进程或线程的定义与创建。

2.利用两个并发运行的进程,实现互斥算法和有界缓冲区同步算法。

四、实验方案指导该实验方案由以下几个关键设计项目组成:1.并发访问出错。

即设计一个共享资源,创建两个并发线程,二者并发访问该共享资源。

当没有采用同步算法设计时,线程所要完成的某些操作会丢失。

2.互斥锁。

并发线程使用线程库提供的互斥锁,对共享资源进行访问。

3.软件方法。

设计并编程实现计数信号量、P操作函数、V操作函数,并发线程通过调用P,V操作函数实现线程的互斥。

4.同步访问多缓冲区。

利用上面的软件方法完成P,V操作,可实现两个线程对多缓冲区的同步访问。

五、实验方案实现范例以下是对该项目中包含的部分设计功能的实现方法、实现过程、技术手段的描述,供师生参考。

1.模拟线程并发运行。

假设我们使用POSIX线程库,而POSIX并没有真正提供线程间的并发运行需求。

我们设计的系统应支持符合RR调度策略的并发线程,每个线程运行一段时间后自动挂起,另一个线程开始运行。

这样一个进程内所有线程以不确定的速度并发执行。

2.模拟一个竞争条件——全局变量。

实验一 进程互斥 实验报告

实验一 进程互斥 实验报告
三、主要器材设备和原料
1.PC微机。
2.Windows操作系统。
3.C语言开发集成环境。
四、实验过程和步骤(比如流程图)
1.本实验具体要求
在同一个进程地址空间内执行的两个进程,生产者进程生产产品,然后将产品放置在一个空缓冲区中供消费者进程消费。消费者进程从缓冲区中获得产品,然后释放缓冲区。当生产者进程生产产品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者进程释放出一个空缓冲区。当消费者进程消费产品时,如果缓冲区为空,那么消费者进程将被阻塞,直到新的产品被生产出来。
计算机操作系统
模拟进程同步与互斥
注:实验报告应包含(实验目的,实验原理,主要仪器设备和材料,实验过程和步骤,实验原始数据记录和处理,实验结果和分析,成绩评定)等七项内容。具体内容可根据专业特点和实验性质略作调整,页面不够可附页。
一、实验目的
1、熟悉临界资源的、信号量及PV操作的定义
2、了解进程通信的方法
3、掌握实现进程互斥与同步的方法
4、掌握用信号量机制解决进程之间同步的与互斥的问题
5、实现生产者-消费者问题,深刻理解操作系统对进程的调度顺序及进程同步的概念
二、实验原理(主要写算法思想)
生产者-消费者问题是经典的进程同步问题,在这个问题中,生产者不断的向缓冲池中写入数据,消费者不断的从缓冲区中读取数据。生产者和消费者对缓冲池的操作是互斥的,即当前只能由一个进程对这个缓冲池进行操作。生产者生产时要判断当前缓冲池是否已满,当缓冲池满时,不能再写入,消费者消费时要判断当前缓冲池是否已空,当缓Байду номын сангаас池空时,不能再读取。
(4)当执行消费者进程时,需对产品类型进行选择,当缓冲区有该产品时,则消费者进行消费。

操作系统进程同步与互斥实验报告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.该程序能较好地体现程序并发执行时的一种制约关系-互斥,但不能较好的反映进程的同步关系,所以该算法有待改进,用以同时实现进程的同步和互斥。

进程间的互斥和同步问题(一)

进程间的互斥和同步问题(一)

进程间的互斥和同步问题(一)进程间的互斥和同步问题在多进程编程中,进程间的互斥和同步问题是一个重要的概念。

下面列举了相关的问题,并对其进行解释说明。

1. 互斥问题•定义:互斥指的是多个进程或线程对同一共享资源的访问是否有序的问题。

•问题描述:当多个进程同时竞争一个共享资源时,可能会出现资源竞争和数据不一致的情况。

•解决方案:使用互斥锁(Mutex)来实现对共享资源的互斥访问,保证每一次只有一个进程或线程能够访问该资源。

2. 同步问题•定义:同步指的是多个进程或线程之间如何进行有序的合作和协调。

•问题描述:当多个进程之间存在依赖关系,需要按照特定的顺序执行时,可能会出现数据不一致或死锁的情况。

•解决方案:使用同步机制(如信号量、条件变量等)来实现进程间的同步,保证各个进程按照特定的顺序执行。

3. 死锁问题•定义:死锁是指在多进程或多线程系统中,彼此因争夺资源而陷入无限等待的状态。

•问题描述:当多个进程互相持有对方所需的资源并等待对方释放资源时,可能会导致死锁的发生。

•解决方案:通过合理的资源分配和调度策略,避免进程之间出现相互依赖的情况,从而避免死锁的发生。

4. 临界区问题•定义:临界区是指在多进程或多线程环境中访问共享资源的一段代码区域。

•问题描述:当多个进程同时访问临界区时,可能会出现数据不一致或竞态条件的问题。

•解决方案:使用互斥锁或其他同步机制来保护临界区的访问,只有获得锁的进程才能够执行临界区的代码,其他进程必须等待。

5. 进程间通信问题•定义:进程间通信(IPC,Inter-Process Communication)指的是实现不同进程之间的信息交换和数据传输。

•问题描述:当多个进程之间需要共享数据或进行协作时,需要有效的通信机制来实现数据的传递。

•解决方案:使用各种IPC机制(如管道、消息队列、共享内存等)来实现进程间的通信,保证数据的正确传输和共享。

综上所述,进程间的互斥和同步问题是多进程编程中不可忽视的重要问题,通过合理的设计和使用适当的同步机制,可以有效解决这些问题,提高程序的并发性和可靠性。

实验一生产者消费者问题

实验一生产者消费者问题

实验一生产者消费者问题一、实验目的1.掌握进程(线程)的同步与互斥。

2.掌握生产者消费者问题的实现方法。

3.掌握多线程编程方法。

二、相关函数VC提供一系列函数用于实现多线程编程以及线程的互斥与同步。

(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:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。

main()函数是主线程的入口函数,同样,新创建的线程也需要一个入口函数,lpStartAddress 就是指示该函数的地址。

并且这个函数的定义应遵循下面的声明形式DWORD WINAPI ThreadProc(LPVOID lpParameter);✧lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;✧dwCreationFlags:控制线程创建的附加标志,可以取两种值。

如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于阻塞状态,并不马上执行,直至函数ResumeThread被调用;✧lpThreadId:该参数返回所创建线程的ID;✧函数返回值:如果创建成功则返回线程的句柄,否则返回NULL。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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,实现了写者优先,写者写完了再唤醒读者等待队列,实现了多个读者同步。

相关文档
最新文档