线程同步机制实验报告
进程(线程)同步和互斥实验报告
进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期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.1、通过观察共享数据资源但不受控制的两个线程的并发运行输出结果,体会同步机制的必要性和重要性;2.2、利用现有操作系统提供的同步机制编程实现两线程的有序控制;2.3、根据同步机制的Peterson软件解决方案编程实现同步机制对于同一问题的解决;2。
4、基于程序运行时间长短比较两种同步机制。
三、实验步骤:3.1、编程实现不设置任何线程同步机制的多线程银行转账程序,观察输出结果。
3。
1。
1、主要代码(完整代码见附录)://nAccount1与nAccount2为全局变量,也是此线程同步机制里的临界变量.do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop++;} while ((nAccount1 + nAccount2) == 0);3.1.2、输出结果:当没有任何线程同步机制时,程序循环不了多少次便跳了出来,某一次的输出结果如下图:图一无线程同步机制时的程序运行结果3.2、编程实现调用系统Mutex的多线程银行转账程序,观察输出结果。
3。
2.1、:主要代码(完整代码见附录):do{::WaitForSingleObject(m1,INFINITE);nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;if((nAccount1 + nAccount2) != 0)break;::ReleaseMutex(m1);nLoop++;} while (nLoop 〈= 1000000);为了防止程序陷入死循环,在while条件里加上了nloop〈=1000000,当循环执行到第1000001时将跳出。
操作系统线程同步实验报告
线程同步实验报告
实验目的:讨论临界区问题及其解决方案。
实验内容:首先创建两个共享数据资源的并发进程,然后分别在没有同步控制机制、采用mutex机制以及使用软件方法(Peterson)的情况下探究并尽量解决所产生的异常情况。
实验结果:(一)结果截图
1、没有同步控制机制
2、使用mutex机制(其中run1、run2是标志进程输出次数)
3、Peterson算法
(二)结果分析
按照输出结果的稳定性来评判一个程序的好坏,那么大体可以总结为:没有使用同步控制机制<mutex机制<软件机制。
mutex机制是实现由一个进程对公共资源进行访问的时候,不允许其它进程对此资源进行访问。
保证了进程之间的互斥性。
软件机制是使用Peterson算法实现进程间的轮流进行以及进程之间的互斥性。
但是实验结果显示每一种方法均存在异常情况,即在一定次数后程序结束。
产生异常的原因大致分为以下几种:1、进程间的相互影响导致在访问同一个共同资源时会出现变量值与理论值产生偏差,使得不满足循环条件;2、针对单处理机的程序在处理多处理机的问题上会出现偏差;3、PC机本身内存可能存在的部分遗留的数据会影响数据的运算。
操作系统实验报告—Windows线程同步机制
2012-2013学年第一学期计算机操作系统实验报告专业:班级:学号:姓名:提交日期:Windows线程同步机制【开发语言及实现平台或实验环境】C++/C#Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET【实验目的】(1) 了解Windows线程同步机制;(2) 了解互斥体,并通过查阅资料理解互斥体对象的使用方法;(3) 了解事件,并通过查阅资料理解事件对象的使用方法;(4) 了解关键区,并通过查阅资料理解关键区对象的使用方法;(5) 了解信号量,并通过查阅资料理解信号量对象的使用方法;(6) 利用Windows线程同步机制,模拟生产者消费者问题。
【实验要求】(1) 逐程序进行简要分析、运行各程序并仔细阅读注释;(2) 查阅MSDN或其他资料,掌握相关系统调用使用方法和参数含义;(3) 完成实验报告。
【实验步骤】(1) 阅读和理解2-1(mutex).cpp文件中的程序,运行2-1(mutex).cpp,认真观察结果。
然后将两个子函数中注释掉的Sleep语句让其可用,再多次运行,认真观察结果,不会出现销售异常情况。
比较修改程序前后运行结果发生的变化,并分析其原因。
(2) 2-2(event).cpp、2-3(critical_section).cpp的处理方式同(1)。
(3) 阅读和理解2-4(Producer_Consumer).cpp文件中的程序,运行2-4(Producer_Consumer).cpp,认真观察结果,先生产后消费。
然后将两个子函数中注释掉的while语句让其可用,再多次运行,认真观察结果,生产者和消费者保持同步。
比较修改程序前后运行结果发生的变化,并分析其原因。
(4) 阅读和理解2-4(Producer_Consumer)1.cpp文件中的程序,运行2-4(Producer_Consumer)1.cpp,认真观察结果。
实验三 操作系统中的线程同步
实验三操作系统中的线程同步一、实验目的1、加深对线程的理解、掌握Windows中线程的操作。
2、掌握信号量、互斥量、事件、临界区等同步对象的使用。
二、实验理论基础及教材对应关系1、进程和线程的关系。
2、线程间的同步和通信。
3、本实验内容主要对应于教材第2章中关于线程的各节、第3章中关于死锁的各节。
三、实验内容与步骤1、定义全局变量int i = 0; 初始值置为0。
2、创建两个线程,一个对i 执行加1 操作,另一个对i 执行减1 操作。
两个线程执行相同的次数。
显然,正常情况下,i 的仍然保持为0。
#include <stdio.h>#include <windows.h>#define MaxCount 9000000 // 循环次数要很大,可多次尝试一些值DWORD __stdcall fun1( LPVOID p1){for( int j =0 ;j < MaxCount;j++){i++;}return 0;}DWORD __stdcall fun2( LPVOID p1){for( int j =0 ;j < MaxCount;j++){i--;}return 0;}3、观察两个线程执行后的情况,可以发觉最后i 的值不一定是0,有时是很大的正数,有时是很大的负数,这就是多个线程在操作同一个变量i时,未同步时带来的严重问题。
还应该了解,在多个线程操作共享的变量时,才需要考虑同步问题。
1、给这两个线程加上同步代码,再来观察对 i 值的影响。
步骤2的函数稍微改动即可:CRITICAL_SECTION cs;DWORD __stdcall fun1( LPVOID p1){for( int j =0 ;j < MaxCount;j++){::EnterCriticalSection(&cs);i++;::LeaveCriticalSection(&cs);}}DWORD __stdcall fun2( LPVOID p1){for( int j =0 ;j < MaxCount;j++){::EnterCriticalSection(&cs);i--;::LeaveCriticalSection(&cs);}}加入的同步代码的两个线程,无论如何执行,i 的值总是 0 ,结果是正确的。
操作系统线程同步机制实验报告
操作系统线程同步机制实验报告一、实验目的本实验旨在通过对操作系统线程同步机制的实验,深入了解操作系统中线程的运行和同步原理,掌握线程同步机制的使用方法以及安全性问题。
二、实验背景在操作系统中,线程是实现多任务并发执行的基本单位。
为了确保线程的安全性,避免出现竞态条件等问题,需要采取合适的线程同步机制。
三、实验内容1.实现基本的线程同步操作通过使用互斥锁和条件变量,实现以下线程同步问题:(1)生产者/消费者问题:生产者线程生产一定数量的产品,消费者线程从缓冲区中取出产品并消费。
(2)读者/写者问题:多个读者线程可以同时读取共享资源,但是写者线程获取写权限后,其他线程无法读取或写入。
2.实验操作步骤(1)设计和实现多线程程序,包括生产者线程、消费者线程、读者线程和写者线程。
(2)使用互斥锁和条件变量对共享资源进行同步操作,保证线程的安全性。
(3)编译并运行程序,观察线程的执行顺序和结果是否符合预期。
四、实验结果与分析1.生产者/消费者问题通过设计合适的缓冲区和互斥锁,保证生产者线程和消费者线程的安全访问。
实验结果表明,生产者线程可以正确地生产产品,并将产品存储到缓冲区中。
消费者线程可以从缓冲区中取出产品并消费。
2.读者/写者问题通过使用互斥锁和条件变量,实现多个读者线程可以同时读取共享资源,但是写者线程获取写权限后,其他线程无法读取或写入。
实验结果表明,读者线程可以同时读取共享资源,而写者线程获取写权限后,其他线程无法读取或写入。
五、实验总结本实验通过对操作系统线程同步机制的实验,深入了解了操作系统中线程的运行和同步原理,掌握了线程同步机制的使用方法以及安全性问题。
实验结果表明,在设计合适的缓冲区和使用适当的同步机制的情况下,可以有效地保证线程的安全性和正确的并发执行。
六、实验心得通过本次实验,我深刻理解了线程同步机制在操作系统中的重要性。
线程同步机制可以保证多个线程正确地访问共享资源,避免竞态条件等问题的出现。
操作系统 实验四 线程同步
集美大学计算机工程学院实验报告课程名称:操作系统指导教师:王丰实验成绩:实验编号:实验四实验名称:线程同步班级:计算12姓名:学号:上机实践日期:2015.5上机实践时间:2学时一、实验目的1、掌握在Linux环境下的线程创建: clone();2、线程同步:信号灯sem_t实现线程同步与互斥;3、实现经典同步问题读者-写者问题。
二、实验环境Ubuntu-VMware、Linux三、实验内容1、用信号灯 + PV操作实现读者—写者问题;2、用clone()函数4个读者线程和4个写者线程;3、每次读者在共享数据区(缓冲区)读操作,或者写者在共享数据区写操作时,要显示当前正在操作的线程;4、按读者优先或者写者优先编写程序,但要明确是那个优先。
函数和变量1)信号灯:头部文件:semaphore.h (线程:pthread.h)2)信号灯初始化:sem_t r_w_w, mutex;//定义信号灯初始化:sem_init(&r_w_w, 0, 1);sem_init(&mutex,0, 1);3)信号灯操作:对信号等进行P操作:sem_wait(&r_w_w);sem_wait(&mutex);对信号灯进行V操作:sem_post(&r_w_w);Sem_post(&mutex);四、实现过程#include <stdio.h>#include <semaphore.h>#include <pthread.h>#include <stdlib.h>#include <sched.h>//定义信号灯变量sem_t r_w_w;sem_t mutex;int readCount=0;char info[20];//共享数据区int Reader(int r_n){char rc[20];while(1){sem_wait(&mutex);readCount++;if(readCount==1){sem_wait(&r_w_w);printf(“First reader inter CR!\n”); }sem_post(&mutex);printf(“ %dth reader is reading:”,r_n);strcpy(rc,info);printf(“%s\n”,rc);sem_wait(&mutex);readCount--;if(readCount==0)sem_post(&r_w_w);printf(“%dth reader exit.\n”,r_n);sem_post(&mutex);}}int Writer(int w_n){char ws[20];sprintf(ws,”%dth writer”,wn);while(1){sem_wait(&r_w_w);strcpy(info,ws);sem_post(&r_w_w);}}main(){int i,arg;int clone_flag;char *stack;sem_init(&r_w_w,0,1);sem_init(&mutex,0,1);clone_flag=CLONE_VM|CLONE_SIGHAND |CLONE_FS|CLONE_FILES; for(i=0;i<4;i++){arg=i+1;stack=(char *) malloc(4096);clone((void *)Reader,&(stack[4096]),clone_flag,(void *)&arg);stack=(char *) malloc(4096);clone((void *)Writer,&(stack[4096]),clone_flag,(void *)&arg);}exit(1);}1)查看当前root目录下文件2)将ls输出,输入到文件ttt中3)查看4)向文件ttt中追加内容3.后台进程、管道操作①后台命令后台执行进程a.out4.Shell程序①无参数的Shell程序②shell程序的位置参数1)编写shell程序2)编译及运行结果分析:在运行时带了5个参数,于是argc=5,然后将这五个参数依次输出到屏幕。
操作系统实验线程的同步
实验六线程的同步1、实验目的(1)进一步掌握Windows系统环境下线程的创建与撤销。
(2)熟悉Windows系统提供的线程同步API。
(3)使用Windows系统提供的线程同步API解决实际问题。
2、实验准备知识:相关API函数介绍①等待对象等待对象(wait functions)函数包括等待一个对象(WaitForSingleObject())和等待多个对象(WaitForMultipleObject())两个API函数。
1)等待一个对象WaitForSingleObject()用于等待一个对象。
它等待的对象可以为以下对象之一。
·Change ontification:变化通知。
·Console input: 控制台输入。
·Event:事件。
·Job:作业。
·Mutex:互斥信号量。
·Process:进程。
·Semaphore:计数信号量。
·Thread:线程。
·Waitable timer:定时器。
原型:DWORD WaitForSingleObject(HANDLE hHandle, // 对象句柄DWORD dwMilliseconds // 等待时间);参数说明:(1)hHandle:等待对象的对象句柄。
该对象句柄必须为SYNCHRONIZE访问。
(2)dwMilliseconds:等待时间,单位为ms。
若该值为0,函数在测试对象的状态后立即返回,若为INFINITE,函数一直等待下去,直到接收到一个信号将其唤醒,如表2-1所示。
返回值:如果成功返回,其返回值说明是何种事件导致函数返回。
Static HANDLE hHandlel = NULL;DWORD dRes;dRes = WaitForSingleObject(hHandlel,10); //等待对象的句柄为hHandlel,等待时间为10ms 2)等待对个对象WaitForMultiple()bject()在指定时间内等待多个对象,它等待的对象与WaitForSingleObject()相同。
建立线程的实验报告(3篇)
第1篇一、实验目的1. 理解线程的概念和作用;2. 掌握在C++中创建和使用线程的方法;3. 了解线程同步机制,如互斥锁、条件变量等;4. 分析线程间的通信和协作。
二、实验环境1. 操作系统:Windows 102. 编译器:Visual Studio 20193. 编程语言:C++三、实验内容本次实验主要分为以下几个部分:1. 线程的基本概念和作用;2. 创建和使用线程;3. 线程同步机制;4. 线程间的通信和协作。
四、实验步骤1. 线程的基本概念和作用线程是程序执行过程中的一个独立单位,它包含程序执行所需的基本信息,如程序计数器、寄存器等。
线程的主要作用是提高程序的执行效率,实现并发执行。
2. 创建和使用线程在C++中,可以使用`std::thread`类来创建线程。
以下是一个简单的例子:```cppinclude <iostream>void printNumber(int n) {for (int i = 0; i < n; ++i) {std::cout << i << std::endl;}}int main() {std::thread t1(printNumber, 10); // 创建线程,传入函数和参数std::thread t2(printNumber, 20);t1.join(); // 等待线程t1执行完毕t2.join(); // 等待线程t2执行完毕return 0;}```在上面的代码中,我们创建了两个线程`t1`和`t2`,分别执行`printNumber`函数。
使用`join`函数可以等待线程执行完毕。
3. 线程同步机制线程同步机制用于解决多线程在执行过程中可能出现的数据竞争、死锁等问题。
以下是一些常用的线程同步机制:(1)互斥锁(Mutex)互斥锁用于保护共享资源,确保同一时刻只有一个线程可以访问该资源。
以下是一个使用互斥锁的例子:```cppinclude <iostream>include <mutex>std::mutex mtx;void printNumber(int n) {mtx.lock(); // 获取互斥锁for (int i = 0; i < n; ++i) {std::cout << i << std::endl;}mtx.unlock(); // 释放互斥锁}int main() {std::thread t1(printNumber, 10);std::thread t2(printNumber, 20);t1.join();t2.join();return 0;}```(2)条件变量(Condition Variable)条件变量用于在线程间实现等待和通知机制。
线程同步实验报告(A39)
广州商学院操作系统实验报告(第4次)实验名称:实验六线程同步一、实验目的1. 加深理解线程同步的概念及实现线程同步的原理。
2. 掌握Linux线程库支持的信号量同步机制和信号量互斥机制,学会通过信号量信号实现线程间的同步与互斥。
二、实验内容实验七、线程同步实现公交车司机与售票员同步,参考实验四,完成该程序的设计三、原理和实验主要步骤1、原理:Linux的线程库中定义了同步信号量以及多种同步信号量操作函数(原语)。
POSIX信号量同步信号量的类型为sem_t基本的同步信号量操作函数有4个:sem_init( )sem_wait( )(相当于P操作)sem_post( )(相当于V操作)sem_destroy( )它们均在头文件semaphore.h中声明。
sem_init 函数原型:int sem_init(sem_t *sem, int type, int value);其中,参数sem为同步信号量的指针;type为信号量类型,若为0,表示该信号量是现行进程的局部信号量(只在现行进程的线程之间使用),否则,它可为多个进程所共享;value 是信号量值的初值。
功能:初始化同步信号量。
sem_wait 函数原型:int sem_wait(sem_t *sem);功能:同步信号量的P操作sem_post 函数原型:int sem_post(sem_t *sem);功能:同步信号量的V操作sem_destroy 函数原型:int sem_destroy(sem_t *sem);功能:清理同步信号量上述函数返回0表示成功,非0表示失败。
2、本实验要求应用Linux线程库支持的信号量互斥机制改进实验4.2,即程序test4_2.c。
该互斥机制的内容见讲义Unit 4中的4.2节。
本实验的程序框架和部分程序代码如下,请完成该程序的设计,/*test6_1.c*/#include<stdio.h>#include<pthread.h>int ticket[10]={1,3,5,7,9,2,4,6,8,10};int rest=10;int th_num[2]={1,2}; /*自定义的线程序号*/<定义一个互斥信号量>void *terminal(void *p) /*售票终端线程代码*/{ int mynum=*((int *)p); /*本终端的序号*/int tot=0; /*本终端售票计数*/<你的设计部分>printf(“Terminal_%d selled %d tickets .\n”, mynum,tot);pthread_exit(0);}int main( ){pthread_t tid[2];<初始化信号量>pthread_create(&tid[0], NULL, terminal, &th_num[0]);/*参数“&th_num[0]”是线程的入口参数*/pthread_create(&tid[1], NULL, terminal, &th_num[1]);<等待线程终止><撤消信号量><结束>}问题描述:公共汽车上,司机和售票员的活动分别是:司机的活动:启动车辆;正常行车;到站停车。
并发执行实验报告
一、实验目的1. 了解并发执行的概念和原理。
2. 学习并发编程技术,提高程序执行效率。
3. 通过实验验证并发执行对程序性能的影响。
二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:IntelliJ IDEA4. 并发框架:Java并发包(java.util.concurrent)三、实验内容1. 实验一:线程同步2. 实验二:线程池3. 实验三:并发容器4. 实验四:Future和Callable四、实验步骤1. 实验一:线程同步(1)创建一个共享资源,用于模拟多个线程对资源的访问。
(2)使用synchronized关键字实现线程同步。
(3)比较同步前后程序执行时间。
2. 实验二:线程池(1)创建一个线程池,并提交多个任务到线程池中执行。
(2)比较线程池和普通线程执行任务的效率。
3. 实验三:并发容器(1)使用并发容器(如ConcurrentHashMap)和普通容器(如HashMap)进行数据操作。
(2)比较两种容器在并发环境下的性能差异。
4. 实验四:Future和Callable(1)使用Callable接口和Future接口实现异步计算。
(2)比较使用Future和Callable前后程序执行时间。
五、实验结果与分析1. 实验一:线程同步实验结果显示,在同步前,程序执行时间为5秒;在同步后,程序执行时间为2秒。
这说明线程同步可以有效地提高程序执行效率。
2. 实验二:线程池实验结果显示,在普通线程环境下,程序执行时间为10秒;在线程池环境下,程序执行时间为6秒。
这说明线程池可以显著提高程序执行效率。
3. 实验三:并发容器实验结果显示,在并发环境下,使用并发容器(如ConcurrentHashMap)的平均执行时间为1秒,而使用普通容器(如HashMap)的平均执行时间为3秒。
这说明并发容器在处理并发操作时具有更好的性能。
4. 实验四:Future和Callable实验结果显示,使用Future和Callable接口实现异步计算后,程序执行时间为4秒;而同步执行程序执行时间为8秒。
操作系统实验5-线程的同步
else if(dRes==WAIT_OBJECT_0) printf("WAIT_T!dRes=%d\n",dRes);
else if(dRes==WAIT_ABANDONED) printf("WAIT_ABANDONED!dRes=%d\n",dRes);
一台装有WindowsXP或Winddows2003的机器(这里默认是WindowsXP).
要求:能正确使用等待对象WaitForSingleObject()或WaitForMultipleObject()及信号量对象CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()等系统调用,进一步理解线程的同步。
elseprintf("dRes=%d\n",dRes);
CloseHandle(h1);
CloseHandle(hHandle1);
ExitThread(0);
return nRetCode;
}
void func()
{
BOOL rc;
DWORD err;
printf(" Now In Thread !\n");
rc=ReleaseSemaphore(hHandle1,1,NULL); //子线程唤醒主线程
err=GetLastError();
printf("ReleaseSemaphore err=%d\n",err);
if (rc==0) printf("Semaphore Release Fail!\n");
同步机制实验报告
一、实验目的1. 理解同步机制的基本概念和原理;2. 掌握不同同步机制(如互斥锁、条件变量、信号量等)的使用方法;3. 通过实验验证同步机制在解决并发编程中的同步和互斥问题。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容本次实验主要涉及以下同步机制:1. 互斥锁(Mutex)2. 条件变量(Condition Variable)3. 信号量(Semaphore)1. 互斥锁(Mutex)(1)实验目的:验证互斥锁在解决临界区访问冲突问题中的作用。
(2)实验步骤:1)定义互斥锁对象;2)创建多个线程,每个线程尝试访问临界区;3)在访问临界区之前,使用互斥锁进行加锁和解锁操作。
(3)实验结果:实验结果显示,在多个线程访问临界区时,互斥锁成功避免了冲突,确保了临界区的安全访问。
2. 条件变量(Condition Variable)(1)实验目的:验证条件变量在解决生产者-消费者问题中的作用。
(2)实验步骤:1)定义条件变量对象和互斥锁对象;2)创建生产者线程和消费者线程;3)生产者在生产数据时,使用条件变量通知消费者;4)消费者在消费数据时,使用条件变量等待生产者通知。
(3)实验结果:实验结果显示,在多个生产者和消费者线程并发执行时,条件变量成功实现了生产者和消费者之间的同步,避免了生产者和消费者之间的冲突。
3. 信号量(Semaphore)(1)实验目的:验证信号量在解决线程同步问题中的作用。
(2)实验步骤:1)定义信号量对象;2)创建多个线程,每个线程在执行任务前,需要等待信号量释放;3)在任务完成后,释放信号量,以便其他线程执行。
(3)实验结果:实验结果显示,在多个线程并发执行时,信号量成功实现了线程之间的同步,确保了线程按照预期顺序执行。
四、实验总结通过本次实验,我们深入了解了同步机制的基本概念和原理,掌握了互斥锁、条件变量和信号量等同步机制的使用方法。
Windows的多线程同步实验报告
一、实验目的在掌握基于消息的windows程序结构和多线程程序设计方法的基础上,设计一个多线程同步的程序。
使学生能够从程序设计的角度了解多线程程序设计的方法和在windows系统下多线程同步互斥的机制。
二、实验内容1.理解Windows程序设计的基本思想,理解基于消息的程序设计方法,能够设计出简单的基于事件的windows程序,完成基本控件的使用2.结合操作系统中信号量与互斥体的概念,在MFC中找到对应的相关类3.设计一个多线程同步的程序,多线程概述进程和线程都是操作系统的概念。
进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。
系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。
主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。
用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。
一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛。
多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。
要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。
由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。
这一点在多线程编程时应该注意。
Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作。
线程同步机制实验报告
线程同步机制实验报告通过观察共享数据资源但不受控制的两个线程的并发运行输出结果,体会同步机制的必要性和重要性。
然后利用现有操作系统提供的同步机制编程实现关于该两个线程的有序控制,同时要求根据同步机制的Peterson软件解决方案尝试自己编程实现同步机制和用于同一问题的解决,并基于程序运行时间长短比较两种同步机制。
二、实验内容:1、基于给定银行账户间转账操作模拟代码作为线程执行代码,在主线程中创建两个并发线程,编程实现并观察程序运行结果和予以解释说明。
(无同步机制)2、利用Win32 API中互斥信号量操作函数解决上述线程并发问题,并分析、尝试和讨论线程执行体中有关信号量操作函数调用的正确位置。
3、根据同步机制的Peterson软件解决方案尝试自己编程实现线程同步机制和用于上述线程并发问题的解决,并基于程序运行时间长短将其与基于Win32 API互斥信号量的线程同步机制的效率展开比较。
其间,可规定线程主体代码循环执行1000000次。
三、实验环境:操作系统:Windows 7软件:VC++6.0●本实验包含三个基于并发线程的程序,第一个没有同步机制,第二个利用Win32 API中互斥信号量操作函数解决线程并发问题,第三个根据同步机制的Peterson软件解决方案实现线程同步机制并解决线程并发问题。
三个程序拥有相同的线程主体:线程主体设计:do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop++;} while ((nAccount1 + nAccount2)==0);该线程主体是对银行账户间转账操作模拟的模拟,可知,若并发的线程不发生交叉,则依次转账操作后nAccount1 + nAccount2的值永远为0,程序不会跳出循环,如果线程发生交叉,则经过若干次转账操作后,就有可能出现nAccount1 + nAccount2不为0的情况,此时程序跳出循环。
线程控制实验报告(3篇)
第1篇一、实验背景线程是操作系统中实现并发执行的基本单位,它允许程序在同一时间内执行多个任务。
线程控制实验旨在通过实际操作,加深对线程概念、线程同步与互斥机制的理解,并掌握线程的创建、同步与互斥方法。
二、实验目的1. 理解线程的概念及其在操作系统中的作用。
2. 掌握线程的创建、同步与互斥方法。
3. 熟悉线程调度与同步在实际编程中的应用。
4. 通过实验,提高对多线程编程的理解和实际操作能力。
三、实验环境操作系统:Windows 10编程语言:Java开发工具:Eclipse四、实验内容1. 线程的创建与启动实验步骤:(1)创建一个名为ThreadDemo的Java类,继承自Thread类。
(2)在ThreadDemo类中重写run()方法,实现线程要执行的任务。
(3)在main方法中创建ThreadDemo类的实例,并调用start()方法启动线程。
实验代码:```javapublic class ThreadDemo extends Thread {@Overridepublic void run() {// 线程要执行的任务System.out.println("线程运行:" +Thread.currentThread().getName());}public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();threadDemo.start(); // 启动线程}}```2. 线程同步与互斥实验步骤:(1)创建一个名为SyncDemo的Java类,包含一个共享资源和一个同步方法。
(2)在SyncDemo类中,使用synchronized关键字声明同步方法,实现线程间的同步。
(3)在main方法中创建多个ThreadDemo类的实例,并启动线程,观察线程同步与互斥的效果。
实验代码:```javapublic class SyncDemo {private int count = 0;public synchronized void increment() {count++;System.out.println(Thread.currentThread().getName() + ":count=" + count);}public static void main(String[] args) {SyncDemo syncDemo = new SyncDemo();Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {syncDemo.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {syncDemo.increment();}});thread1.start();thread2.start();}}```3. 线程通信实验步骤:(1)创建一个名为ThreadCommunication的Java类,包含一个共享资源和一个同步方法。
线程实验报告的原理(3篇)
第1篇一、引言随着计算机技术的飞速发展,多线程编程已经成为现代软件开发中不可或缺的一部分。
线程实验报告旨在通过一系列实验,让学生深入理解线程的概念、原理和应用,提高学生在多线程编程方面的实践能力。
本文将从线程的基本概念、原理、编程模型和常见问题等方面,详细阐述线程实验报告的原理。
二、线程的基本概念1. 什么是线程?线程是操作系统能够进行运算调度的最小单位,它是系统进行计算和任务分配的基本单元。
线程与进程相比,具有以下特点:(1)线程是进程的一部分,一个进程可以包含多个线程。
(2)线程的创建、销毁和切换等操作比进程更加高效。
(3)线程共享进程的地址空间、数据段和文件描述符等资源。
2. 线程的分类根据线程的调度方式和执行环境,线程可分为以下几类:(1)用户级线程(User-level Thread):由应用程序创建和管理,操作系统不直接支持。
(2)内核级线程(Kernel-level Thread):由操作系统创建和管理,线程调度由操作系统负责。
(3)混合级线程(Hybrid-level Thread):结合用户级线程和内核级线程的优点,线程创建、销毁和切换等操作由应用程序负责,调度由操作系统负责。
三、线程的原理1. 线程的状态线程在执行过程中,可能处于以下几种状态:(1)新建(New):线程被创建后,处于新建状态。
(2)就绪(Runnable):线程准备好执行,等待被调度执行。
(3)运行(Running):线程正在执行。
(4)阻塞(Blocked):线程因等待某个资源或其他原因而无法执行。
(5)等待(Waiting):线程在等待某个条件成立时,主动放弃CPU资源。
(6)超时等待(Timed Waiting):线程在等待某个条件成立时,设定一个超时时间。
(7)终止(Terminated):线程执行完毕或被强制终止。
2. 线程的调度线程的调度是指操作系统从就绪队列中选择一个线程执行的过程。
线程调度策略主要有以下几种:(1)先来先服务(FCFS):按照线程创建的顺序进行调度。
重庆大学操作系统实验三(线程同步)
重庆大学操作系统实验三(线程同步)重庆大学学生实验报告实验课程名称操作系统原理开课实验室重庆大学DS1501 学院软件工程年级 2013 专业班学生姓名学号开课时间 2015 至 2016 学年第一学期重庆大学软件学院制《操作系统原理》实验报告三、使用仪器、材料(软硬件开发环境)Notepad++expenv四、实验步骤(实现的过程)//定义信号量结构体struct semaphore{int value;/*processes blocked by this semaphore*/struct wait_queue*wq_kbd;};sem.c:void*sys_sem_create(int value){struct semaphore*hsem;char*p;p=(char*)kmalloc(sizeof(struct semaphore));hsem=(struct semaphore*)p;hsem->value=value;//赋初值hsem->wq_kbd=NULL;//非常重要if(hsem==NULL)return NULL;else return(struct semaphore*)hsem;//成功返回信号量句柄hsem }int sys_sem_destroy(void*hsem){kfree(hsem);return0;}int sys_sem_wait(void*hsem){uint32_t flags;save_flags_cli(flags);((struct semaphore*)hsem)->value--;//P操作if(((struct semaphore*)hsem)->value<0){sleep_on(&(((struct semaphore*)hsem)->wq_kbd));}restore_flags(flags);return0;}int sys_sem_signal(void*hsem){uint32_t flags;save_flags_cli(flags);((struct semaphore*)hsem)->value++;//V操作if(((struct semaphore*)hsem)->value<=0){wake_up(&(((struct semaphore*)hsem)->wq_kbd),1);//等待队列中唤醒一个线程}restore_flags(flags);return0;}把这四个函数做成系统调用 sem_create/destroy/wait/signalgraphics.c中//定义一个表示信号量的全局变量static void*hsem=NULL;hsem=sem_create(1);//创建信号量sem_destroy(hsem);//销毁信号量以及sem_wait(hsem);//用信号量hsem保护画点临界区switchBank(HIWORD(addr));*p=getBValue(cr);*(p+1)=getGValue(cr);*(p+2)=getRValue(cr);sem_signal(hsem);main.c:声明信号量:# define arrayNumber50#define N4//缓冲区数static void*mutex=NULL;//互斥信号量static void*full=NULL;//已生产产品数static void*empty=NULL;//空闲数int startposition=0;//生产者缓冲区坐标static int count=0; //消费者缓冲区坐标int temp[4][50]={0};int array[N][arrayNumber];生产者消费者函数:void tsk_producer(void*pv){while(1){int i=0;srand((unsigned)time(NULL));sem_wait(empty);//是否有空闲位置?sem_wait(mutex);for(i=0;i<=arrayNumber-1;i++){array[startposition][i]=random()%200;draw(i*10,startposition*230,startposition*230+array[startpo sition][i]);DELAY(100000);}startposition=(++startposition)%N;sem_signal(mutex);sem_signal(full);//有产品生产好}task_exit(0);}void tsk_consumer(void*pv){while(1){sem_wait(full);//还有产品么?sem_wait(mutex);int i;for(i=0;i<=arrayNumber-1;i++){temp[count][i]=array[count][i];}sem_signal(mutex);//让出临界区使生产与消费并行sort_m(temp[count],arrayNumber,count*230); //冒泡排序resetAllBK(temp[count],arrayNumber,count*230); //清空该缓冲区count=(++count)%N;sem_signal(empty);//消费完一个产品}task_exit(0);}主函数:int value=1;mutex=sem_create(value);value=0;full=sem_create(value);value=N;empty=sem_create(value);initGraphics(0x0118);unsigned char*stack_producer=(unsigned char*)malloc(1024*1024);unsigned char*stack_consumer=(unsigned char*)malloc(1024*1024);inttid_producer=task_create(stack_producer+1024*1024,tsk_produ cer,(void*)0);inttid_consumer=task_create(stack_consumer+1024*1024,tsk_cons umer,(void*)0);int setResult1=setpriority(tid_producer,2);int setResult2=setpriority(tid_consumer,2);五、实验结果及分析(实现的效果,包括屏幕截图、系统总体运行情况和测试情况等)empty=sem_create(value);initGraphics(0x0118);unsigned char*stack_producer=(unsigned char*)malloc(1024*1024);unsigned char*stack_consumer=(unsigned char*)malloc(1024*1024);inttid_producer=task_create(stack_producer+1024*1024,tsk_produ cer,(void*)0);inttid_consumer=task_create(stack_consumer+1024*1024,tsk_cons umer,(void*)0);int setResult1=setpriority(tid_producer,2);int setResult2=setpriority(tid_consumer,2);五、实验结果及分析(实现的效果,包括屏幕截图、系统总体运行情况和测试情况等)通过互斥量保护Setpixel解决了实验二优先级调度的花屏现象通过做本实验,我对书本上信号量概念有了实践性的理解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线程同步机制实验报告一、实验目的:通过观察共享数据资源但不受控制的两个线程的并发运行输出结果,体会同步机制的必要性和重要性。
然后利用现有操作系统提供的同步机制编程实现关于该两个线程的有序控制,同时要求根据同步机制的Peterson软件解决方案尝试自己编程实现同步机制和用于同一问题的解决,并基于程序运行时间长短比较两种同步机制。
二、实验内容:1、基于给定银行账户间转账操作模拟代码作为线程执行代码,在主线程中创建两个并发线程,编程实现并观察程序运行结果和予以解释说明。
(无同步机制)2、利用Win32 API中互斥信号量操作函数解决上述线程并发问题,并分析、尝试和讨论线程执行体中有关信号量操作函数调用的正确位置。
3、根据同步机制的Peterson软件解决方案尝试自己编程实现线程同步机制和用于上述线程并发问题的解决,并基于程序运行时间长短将其与基于Win32 API互斥信号量的线程同步机制的效率展开比较。
其间,可规定线程主体代码循环执行1000000次。
三、实验环境:操作系统:Windows 7软件:VC++四、实验设计:本实验包含三个基于并发线程的程序,第一个没有同步机制,第二个利用Win32 API中互斥信号量操作函数解决线程并发问题,第三个根据同步机制的Peterson软件解决方案实现线程同步机制并解决线程并发问题。
三个程序拥有相同的线程主体:线程主体设计:do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop++;} while ((nAccount1 + nAccount2)==0);该线程主体是对银行账户间转账操作模拟的模拟,可知,若并发的线程不发生交叉,则依次转账操作后nAccount1 + nAccount2的值永远为0,程序不会跳出循环,如果线程发生交叉,则经过若干次转账操作后,就有可能出现nAccount1 + nAccount2不为0的情况,此时程序跳出循环。
本实验的三个程序就是基于此线程主体逐步实现的。
同步机制的Peterson软件解决方案五、数据结构设计:程序一:没有同步机制说明:ThreadFunc(HANDLE Thread)为线程函数;nAccount1、aAccount2模拟账户;nLoop记录循环次数;nRandom是产生的随机数模拟转账金额;nTemp1、nTemp2用于暂存nAccount1、aAccount2;HANDLE Thread[2]创建两个线程句柄。
程序二:利用Win32 API中互斥信号量说明:mutex为互斥信号量;time_start、time_end为线程开始运行和结束的时间;time=time_end- time_start。
程序三:同步机制的Peterson软件解决方案说明:flag为长度为2的bool型数组,turn为整型,flag与turn共同实现同步机制的Peterson软件解决方案;nLoop1记录线程0的循环次数;nLoop记录线程1的循环次数。
六、算法流程图:程序一:没有同步机制开始创建两个线程线程1转账线程2转账nAccount1 +nAccount2==0Y输出循环次数结束N N 程序二:利用Win32 API中互斥信号量开始创建两个线程线程1线程2nLoop<1000000Y 输出循环次数结束等待资源WaitForSingleObject(mutex,INFINITE);等待资源WaitForSingleObject(mutex,INFINITE);转账nLoop++;释放资源转账nLoop++;释放资源NN程序三:同步机制的Peterson 软件解决方案开始创建两个线程线程1线程2nLoop1+nLoop2<1000000Y输出循环次数结束等待资源flag[0]=true;turn=1;while(flag[1] &&turn==1){}转账nLoop1++;释放资源转账nLoop2++;释放资源NN等待资源flag[0]=true;turn=1;while(flag[1] &&turn==1){}七、实验过程结果截图:程序一:没有同步机制程序二:利用Win32 API中互斥信号量程序三:同步机制的Peterson软件解决方案八、实验结果分析:第一个程序两个线程并发并没有同步机制,所以产生了nAccount1 + nAccount2不为0的情况,程序跳出循环,一个线程结束,但剩余的一个线程自己是无法跳出循环的,所以程序一直在运行;第二个程序利用互斥信号并通过成功资源资源来解决并发带来的混乱;第三个程序通过同步机制的Peterson软件解决方案解决并发带来的混乱;通过结果可知,同步机制的Peterson软件解决方案的效率要高于利用Win32 API中互斥信号量的方法。
九、实验总结:实验心得:通过本次实验,我锻炼里自己的编程能力,并对理论知识有了进一步的理解。
对线程并发问题有了进一步的体会,并掌握了同步线程的方法,特别是同步机制的Peterson软件解决方案。
同时我也体会到,学好这门课程,不光要掌握好理论,更重要的是要多实践,对实验现象多加分析研究,才会融会贯通所学的内容。
实验评价:本实验按照实验指导书完成了要求的全部内容,成功得出了结果。
但实验程序也存在一些潜在的漏洞,比如第三个程序在多次执行中会出现总的循环次数不为1000000的情况,有待进一步完善。
十、实验程序清单:程序一:没有同步机制#include <>#include<>#include<>#include<iostream>using namespace std;int nAccount1=0, nAccount2=0;int nLoop=0;int nTemp1,nTemp2,nRandom;DWORD WINAPI ThreadFunc(HANDLE Thread){do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop++;} while ((nAccount1 + nAccount2)==0);printf("循环次数为%d\n", nLoop);return 0;}int main(){HANDLE Thread[2];Thread[0]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);Thread[1]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);WaitForMultipleObjects(2,Thread,TRUE,INFINITE);CloseHandle(Thread);return 0;}程序二:利用Win32 API中互斥信号量#include <>#include <>#include <>#include<iostream>using namespace std;#define COUNT 1000000int nAccount1 = 0, nAccount2 = 0;int nLoop = 0;int nTemp1, nTemp2, nRandom;HANDLE mutex;DWORD WINAPI ThreadFunc(LPVOID lpParamter){WaitForSingleObject(mutex,INFINITE);do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop++;ReleaseMutex(mutex);WaitForSingleObject(mutex,INFINITE);}while (nAccount1+nAccount2 == 0 && nLoop<COUNT);printf("循环次数为%d\n", nLoop);ReleaseMutex(mutex);return 0;}int main(){long time;HANDLE Thread[2];DWORD time_start, time_end;time_start = GetTickCount();mutex = CreateMutex(NULL,FALSE,"screen");Thread[0] = CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);Thread[1] = CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);WaitForMultipleObjects(2,Thread,TRUE,INFINITE);CloseHandle(Thread);CloseHandle(mutex);time_end = GetTickCount();time=time_end-time_start;cout<<"总共用时:"<<time<<"ms"<<endl;return 0;}程序三:同步机制的Peterson软件解决方案#include <>#include <>#include<iostream>using namespace std;#define COUNT 1000000int nAccount1=0,nAccount2=0;int nLoop1 = 0;int nLoop2 = 0;int nTemp1=0,nTemp2=0,nRandom;bool flag[2];int turn;HANDLE mutex;DWORD WINAPI ThreadFunc0(HANDLE Thread){flag[0]=true; //这三行是模拟互斥信号量申请turn=1;while(flag[1] && turn==1){}do{nTemp1 = nAccount1;nTemp2 = nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop1++;flag[0]=false; //释放资源flag[0]=true; //这三行是模拟互斥信号量申请turn=1;while(flag[1] && turn==1){}}while((nAccount1+nAccount2)==0 && (nLoop1+nLoop2)<COUNT );cout<<"1循环次数为:"<<nLoop1<<endl;flag[0]=false;return 0;}DWORD WINAPI ThreadFunc1(HANDLE Thread){flag[1]=true; //这三行是模拟互斥信号量申请turn=0;while(flag[0] && turn==0){}do{nTemp1=nAccount1;nTemp2=nAccount2;nRandom = rand();nAccount1 = nTemp1 + nRandom;nAccount2 = nTemp2 - nRandom;nLoop2++;flag[1]=false; //释放资源flag[1]=true; //这三行是模拟互斥信号量申请turn=0;while(flag[0] && turn==0){}}while((nAccount1+nAccount2)==0 && (nLoop1+nLoop2)<COUNT);cout<<"2循环次数为:"<<nLoop2<<endl;flag[1]=false;return 0;}int main(){long time;HANDLE Thread[2];DWORD time_start, time_end;time_start = GetTickCount();Thread[0] = CreateThread(NULL,0,ThreadFunc0,NULL,0,NULL);Thread[1] = CreateThread(NULL,0,ThreadFunc1,NULL,0,NULL);WaitForMultipleObjects(2,Thread,TRUE,INFINITE);CloseHandle(Thread);time_end = GetTickCount();time=time_end-time_start;cout<<"总共用时:"<<time<<"ms"<<endl;cout<<"总次数:"<<nLoop1+nLoop2<<endl;return 0;}。