南昌大学操作系统实验报告二编程模拟进程间的同步和互斥
- 格式:docx
- 大小:1.25 MB
- 文档页数:13
进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2021一、实验题目: : 进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容、组织的变化,理解进程与其 PCB 间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。
3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解 Windows 同步对象及其特性;熟悉实验环境,掌握相关 API 的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h> #include <iostream> #include<stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;#define MA__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;//判断程序能否继续执行的逻辑值 intg_buffer[SIZE_OF_BUFFER];//缓冲区是个循环队列 HANDLE g_hMute_;//公有信号量,用于线程间的互斥 HANDLEg_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);cout << “生产者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_, 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 < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);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_hMute_,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 < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);} }void prod_cons {//创建互斥信号量g_hMute_ = CreateMute_(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0,SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL));//以时间函数为种子const unsigned short THREADS_COUNT = rand % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MA__THREAD_NUM];ThreadInfo thread_info[MA__THREAD_NUM];DWORD thread_ID; //线程 IDint num = 0;//临时变量,用于循环语句cout << “系统开始模拟,并自动生成模拟数据...” << endl;system(“pause”); //暂停确认开始执行cout << “线程总数:” << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand % 2 == 1)thread_info[num].entity = "P";elsethread_info[num].entity = "C";thread_info[num].delay = rand % 5 + 1;thread_info[num].persist = rand % 6 + 2;num++;}cout << “\n 系统生成数据结束,模拟数据如下:” << endl<< “线程号线程类别延迟时间操作时间” << endl;for (int _ = 0;_ < THREADS_COUNT;_++)cout << “” << thread_info[_].serial << “\t”<< “” << thread_info[_].entity << “\t”<< “” << thread_info[_].delay << “\t\t”<< “” << thread_info[_].persist << endl;cout << “\n\n==================生产者-消费者开始==================\n” << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == "P")hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), ;thread_info[i], 0, ;thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), ;thread_info[i], 0, ;thread_ID);}while (running){if (getchar){//按回车后终止程序运行running = false;}}cout << “系统模拟结束...” << endl; } int main {cout << “\n==================生产者-消费者模拟==================\n” << endl;prod_cons; }五、实验过程1、记录生产者和消费者的同步执行过程。
进程的同步与互斥实验报告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.实验总结通过本次实验,我深刻理解了进程(线程)的同步与互斥,并通过实际操作加深了对这些概念的理解。
同步和互斥是操作系统中非常重要的概念,对于应对资源竞争和提高程序性能具有重要意义。
在实际开发中,我们应该合理使用同步和互斥机制,以确保程序的正确性和并发执行的效率。
南昌大学实验报告---(2)编程模拟进程间的同步与互斥学生姓名: 张皓然学号: 5501215001 专业班级: 本硕151实验类型:□验证□综合■设计□创新实验日期: 2017、5、5 实验成绩:一、实验目的通过实验加强对进程同步与互斥的理解,并掌握进程(线程)的创建与调用方法。
学会使用信号量解决资源共享问题。
学生可以自己选择在Windows或Linux系统下编写。
二、实验内容(一)以下为Linux系统下参考程序,请编译、运行并观察程序的输出,并分析实验结果,写出实验报告。
#include<stdio、h>//标准输入输出头文件#include<stdlib、h>//standard library标准库头文件#include<unistd、h>//POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX 系统服务的函数原型,例如read函数、write函数与getpid函数。
#include<time、h>//time、h就是C标准库头文件,主要就是一些与时间相关的函数#include<sys/types、h>//基本系统数据类型#include<sys/wait、h>//declarations for waiting#include<linux/sem、h>//Semaphore operation flags#define NUM_PROCS 5//5个子进程#define SEM_ID 250//信号量#define "/tmp/sem_aaa"#define DELAY 4000000void update_ sem_set_id, char *, int number){struct sembuf sem_op;FILE *建立一个文件指针//等待信号量的数值变为非负数,此处设为负值,相当于对信号量进行P操作sem_op、sem_num=0;sem_op、sem_op=-1;sem_op、sem_flg=0;semop(sem_set_id,&sem_op,1);/*操作一组信号,进程的标识符号为sem_set_id,sem_op就是结构指针。
《操作系统》实验内容实验二编程实现进程(线程)同步和互斥1.实验的目的(1)通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。
(2)了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。
(3)学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。
(4)掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。
(5)掌握多道程序设计的基本理论、方法和技术,培养学生多道程序设计的能力。
2.实验内容在Windows XP、Windows 2000等操作系统下,使用的VC、VB、java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者-消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
3.实验要求(1)经调试后程序能够正常运行。
(2)采用多进程或多线程方式运行,体现了进程(线程)同步和互斥的关系。
(3)程序界面美观。
4.实验步骤(1)需求分析:了解基本原理,确定程序的基本功能,查找相关资料,画出基本的数据流图;(2)概要设计:确定程序的总体结构、模块关系和总体流程;(3)详细设计:确定模块内部的流程和实现算法;(4)上机编码和调试;(5)运行测试;(6)编写实验报告。
5.实验报告要求格式符合《实验报告格式》书;书写规范,排版美观,有较强的文字表达能力,能够正确地表达自己的思想,图表符合规范。
6.实验说明本实验分两次进行,每次要求填写一份实验报告,报告中的实验名分别为:编程实现进程同步和互斥1和编程实现进程同步和互斥2,其他内容依据实验进度具体填写。
《操作系统实验》
实验一:进程的同步和互斥
黄伯虎
实验内容
生产者消费者问题实现
描述:
假设存在两类进程:生产者,消费者。
它们共享n个缓冲区。
生产者行为:生产产品(每次生产1个),并将产品放入空缓冲区,循环往复,永不停息;
消费者行为:将产品从缓冲区中取出,进行消费(每次消费1个),循环往复,永不停息。
规定:缓冲区满,生产者不能放产品;缓冲区空,消费者不能取产品
要求
基本要求
实现当n=1,生产者、消费者各为1个时,同步和互斥过程
扩展要求(可选)
实现当n=c(整常数),生产者、消费者有多个(>1)时,同步和互斥过程平台和工具(原则不限,推荐如下)
Win32平台
VC++6.0
结果显示
字符界面,能说明问题即可
最终成果形式
提交实验报告1份(格式参见附件A)
报告提交时限:下一次实验开始前
提交形式:email
提交的邮件主题请按照如下格式书写:“学号+姓名+实验名称.rar/.doc”
如“030811300+张三+进程同步与互斥.rar/.doc”提交地址:
13班:xdos1@
14,31班:xdos2@。
操作系统实验报告——进程同步与互斥一、实验内容本实验主要内容是通过编写程序来实现进程的同步与互斥。
具体来说,是通过使用信号量来实现不同进程之间的同步和互斥。
我们将编写两个进程,一个进程负责打印奇数,另一个进程负责打印偶数,两个进程交替打印,要求打印的数字从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,表示可以打印偶数。
进程的同步实验报告进程的同步实验报告引言:进程同步是操作系统中一个重要的概念,它涉及到多个进程之间的协调和合作。
在本次实验中,我们将通过一个简单的实例来探讨进程同步的概念和实现方式。
实验目的:通过实验,我们的目标是理解进程同步的概念,学习常见的同步机制,并通过编程实现一个简单的同步问题。
实验环境:本次实验使用了C语言作为编程语言,并在Linux操作系统上进行。
实验过程:我们的实验场景是一个餐厅,有一个厨师和多个服务员。
厨师负责烹饪菜品,服务员负责上菜给客人。
我们需要实现的是,服务员只有在厨师烹饪好一道菜之后才能上菜,否则需要等待。
首先,我们使用互斥锁来实现进程间的同步。
互斥锁是一种常见的同步机制,它可以确保在同一时间只有一个进程可以访问共享资源。
在我们的实验中,厨师和服务员都需要访问菜品资源,因此我们为菜品资源添加了一个互斥锁。
接下来,我们使用条件变量来实现进程间的等待和唤醒操作。
条件变量是一种同步机制,它可以让进程在某个条件满足时等待,直到被唤醒。
在我们的实验中,服务员需要等待厨师烹饪好菜品之后才能上菜,因此我们创建了一个条件变量,并在服务员的代码中使用了等待和唤醒操作。
实验结果:经过实验,我们成功地实现了进程间的同步。
在我们的实验场景中,厨师会不断地烹饪菜品,并在烹饪完成后通知服务员上菜。
服务员会等待厨师的通知,然后上菜给客人。
通过互斥锁和条件变量的使用,我们保证了服务员只会在厨师烹饪完成后才会上菜,避免了资源竞争和错误的上菜行为。
讨论与总结:通过本次实验,我们深入理解了进程同步的概念和实现方式。
互斥锁和条件变量是常见的同步机制,它们可以有效地解决进程间的竞争和协调问题。
在实际的操作系统中,进程同步是一个非常重要的概念,它保证了多个进程之间的正确执行和合作。
然而,进程同步也可能引发一些问题。
例如,如果互斥锁的使用不当,可能会导致死锁的发生。
死锁是一种进程无法继续执行的状态,它会导致系统的停滞。
操作系统实验报告范文模板这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
操作系统上机实验报告班级:学号:姓名:实验地点:实验时间:这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
实验一进程的建立【实验目的】创建进程及子进程在父子进程间实现进程通信【实验软硬件环境】Linu某、Window98、Window2000【实验内容】创建进程并显示标识等进程控制块的属性信息;显示父子进程的通信信息和相应的应答信息。
(进程间通信机制任选)【实验程序及分析】编程思路:首先本程序在Linu某用C语言完成的,父子进程的创建用fork函数来实现,然后是父子进程间的通信,这里用pipe实现。
可以定义chan1[2],chan1[2],chan某[0]表示读,chan某[1]表示写。
他们配合使用。
【实验截图】【实验心得体会】通过这次上机练习,我熟悉了用c++实现进程的创建,销毁,父子进程间的通讯等一系列课程中需要学习的内容。
本来进程的概念在一开始我始终无法清晰地理解,但是通过自己用mfc的方法去实现它后,我开始慢慢地理解操作系统的进程的运作机制。
虽然,我只是实现了一个父子进程的创建和通讯,但是,管中窥豹,我想自己开始明白一个操作系统正是由很多这种进程实现功能的。
其中,系统整体的进程调度,管理等等还有很多东西等着我们去进一步学习、理解。
实验二进程间的同步【实验目的】这是操作系统课程中的四次实验最终报告,内包括进程通信实验,进程同步互斥实验,文件系统模拟实验和Linu某hell操作。
里面的程序都是我运行过的。
理解进程同步和互斥模型及其应用【实验软硬件环境】Linu某、Window98、Window2000【实验内容】利用通信API实现进程之间的同步:建立司机和售票员进程;并实现他们间的同步运行。
南昌大学实验报告---(2)编程模拟进程间的同步和互斥学生姓名:张皓然学号: 5501215001 专业班级:本硕151 实验类型:□验证□综合■设计□创新实验日期: 2017.5.5 实验成绩:一、实验目的通过实验加强对进程同步和互斥的理解,并掌握进程(线程)的创建和调用方法。
学会使用信号量解决资源共享问题。
学生可以自己选择在Windows或Linux系统下编写。
二、实验内容(一)以下为Linux系统下参考程序,请编译、运行并观察程序的输出,并分析实验结果,写出实验报告。
#include<stdio.h>//标准输入输出头文件#include<stdlib.h>//standard library标准库头文件#include<unistd.h>//POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数。
#include<time.h>//time.h是C标准库头文件,主要是一些和时间相关的函数#include<sys/types.h>//基本系统数据类型#include<sys/wait.h>//declarations for waiting#include<linux/sem.h>//Semaphore operation flags#define NUM_PROCS 5//5个子进程#define SEM_ID 250//信号量#define FILE_NAME "/tmp/sem_aaa"#define DELAY 4000000void update_file(int sem_set_id, char *file_path, int number){struct sembuf sem_op;FILE *file;//建立一个文件指针//等待信号量的数值变为非负数,此处设为负值,相当于对信号量进行P操作sem_op.sem_num=0;sem_op.sem_op=-1;sem_op.sem_flg=0;semop(sem_set_id,&sem_op,1);/*操作一组信号,进程的标识符号为sem_set_id,sem_op是结构指针。
操作系统实验-进程同步与互斥实验四:进程的管道通信实验题目进程的管道通信实验目的加深对进程概念的理解,明确进程和程序的区别。
学习进程创建的过程,进一步认识进程并发执行的实质。
分析进程争用资源的现象,学习解决进程互斥的方法。
学习解决进程同步的方法。
掌握Linux系统中进程间通过管道通信的具体实现实验内容使用系统调用pipe()建立一条管道,系统调用fork()分别创建两个子进程,它们分别向管道写一句话,如:Child process1 is sending a message!Child process2 is sending a message!父进程分别从管道读出来自两个子进程的信息,显示在屏幕上。
当然,仅仅通过屏幕上输出这两句话还不能说明实现了进程的管道通信,为了能够更好的证明和显示出进程的同步互斥和通信,在其中要加入必要的跟踪条件,如一定的输出语句等,来反映程序的并发执行情况实验要求这是一个设计型实验,要求自行、独立编制程序。
两个子进程要并发执行。
实现管道的互斥使用。
当一个子进程正在对管道进行写操作时,另一个欲写入管道的子进程必须等待。
使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定。
实现父子进程的同步,当父进程试图从一空管道中读取数据时,便进入等待状态,直到子进程将数据写入管道返回后,才将其唤醒。
为了清楚的反应进程的同步,在子进程完成相应的操作后,调用sleep()函数睡眠一段时间(程序中定为3s)。
父进程先执行wait()函数,当有子进程执行完毕后,会得到子进程的返回结果并清理子进程。
若子进程没执行完,父进程一直执行wait()进行监听,知道有一个子进程执行完成为僵尸进程。
程序中用到的系统调用因为程序时在linux系统上进行编写的,所以其中要利用到相关的linux提供的系统调用。
所用到的系统调用包含在如下头文件中。
#include#include#include#include#include#includefork() 用于创一个子进程。