操作系统实验5:同步机制及应用编程实现与比较

code link: 欢迎star

1. 实验目的

探索、理解并掌握操作系统同步机制的设计和实现机理,针对所谓的银行账户转账同步问题,构建基于Peterson 算法的同步解决方案以及基于Windows(或Linux)操作系统同步机制(主要是互斥机制)的解决方案,并进行分析和比较。

2. 实验内容

针对所谓的银行账户转账同步问题,分析、设计和利用C 语言编程实现基于Peterson 算法的同步解决方案,以及基于Windows(或Linux)操作系统同步机制的相应解决方案,并就自编同步机制与操作系统自身同步机制的效率进行比较和分析。

3. 实验要求

同步机制及应用编程实现与比较实验功能设计要求:

  • 银行账户转账同步问题的抽象及未采取同步控制情况下的编程实现;
  • 基于Peterson 算法的银行账户转账同步问题解决方案;
  • 基于 Windows(或 Linux)操作系统同步机制的银行账户转账同步问题解决方案;
  • Peterson 算法同步机制和Windows(或Linux)操作系统同步机制的效率比较。

4. 实验思路

实验共分为三个部分。

  1. 第一部分,不采用同步控制机制,只在主进程申请两个银行账户的线程来实现对比。这里的核心算法参考实验指导书。
  2. 第二部分,采用Peterson算法进行同步。这里参考了ppt上的介绍,需要定义两个账户两个线程函数。同时添加NLoop上限值进行控制。在这部分,利用编号和标志实现线程的互斥。
  3. 第三部分,采用windows系统的互斥信号量进行同步线程。主要运用参考了实验指导上的函数,包括WaitForSingleObject、ReleaseMutex、CreateMutex。这里我们通过对上边两个部分的总结,将交互输出改为1000个循环一次,这样可以在一屏上输出结果,实验验证性好。
    第四部分,在peterson和windows mutex代码中加入了计时部分,还修改了主线程等待机制,使计时更加准确。控制循环变量,令两者可以比较,MAXNLOOP设为10000次。

5. 程序实现

5.1. 相关环境介绍

操作系统:window 10 21H2
开发环境:Clion-2022.2.1-Windows
编译器:mwing-10.0

5.2. 实验第一部分 无同步机制

01:DWORD WINAPI ThreadExecuteZZW(LPVOID lpParameter){  
02:    int *pID = (int*)lpParameter;  
03:  
04:    int nLoop = 0;  
05:    int nTemp1, nTemp2, nRandom;  
06:    do  
07:    {  
08:        cout << "thread " << *pID << " is called"<< " nLoop is " << nLoop << endl;  
09:        nRandom = rand();  
10:        nTemp1 = nAccount1;  
11:        nTemp2 = nAccount2;  
12:        nAccount1 = nTemp1 + nRandom;  
13:        nAccount2 = nTemp2 - nRandom;  
14:        ++nLoop;  
15:    } while ((nAccount1 + nAccount2) == 0);  
16:  
17:    return 0;  
18:}  

第一部分实验验证
结果符合预期,两个进程相互输出,最后两个账户结果数值之和不为0,实验结束。

5.3. 实验第二部分 Peterson算法

核心代码:

19:#define MAXLOOP 10000  
20:int nAccount1 = 0;  
21:int nAccount2 = 0;  
22:  
23:bool flag[2];  
24:int turn =0;  
25:int nLoop = 0;  
26:DWORD WINAPI ThreadExecuteZZW0(LPVOID lpParameter){  
27:    int *pID = (int *)lpParameter;  
28:    int nTemp1, nTemp2, nRandom;  
29:  
30:    do{  
31:        
32:  
33:        flag[0] = true;  
34:        turn = 1;  
35:        while(flag[1] && turn == 1){};  
36:  			
37:cout << "thread "<< *pID << " is called " << "nLoop is "<< nLoop << endl;  
38:
39:        nRandom = rand();  
40:        nTemp1 = nAccount1;  
41:        nTemp2 = nAccount2;  
42:        nAccount1 = nTemp1 + nRandom;  
43:        nAccount2 = nTemp2 - nRandom;  
44:        ++nLoop;  
45:  
46:        flag[0] = false;  
47:    }while((nAccount1+nAccount2)==0 && nLoop < MAXLOOP);  
48:  
49:    return 0;  
50:}  
51:  
52:DWORD WINAPI ThreadExecuteZZW1(LPVOID lpParameter){  
53:    int *pID = (int *)lpParameter;  
54:    int nTemp1, nTemp2, nRandom;  
55:    do{  
56:         
57:  
58:        flag[1] = true;  
59:        turn = 0;  
60:        while(flag[0] && turn == 0){};  
61:  cout << "thread "<< *pID << " is called " << "nLoop is "<< nLoop << "\n";
62:        nRandom = rand();  
63:        nTemp1 = nAccount1;  
64:        nTemp2 = nAccount2;  
65:        nAccount1 = nTemp1 + nRandom;  
66:        nAccount2 = nTemp2 - nRandom;  
67:        ++nLoop;  
68:  
69:        flag[1] = false;  
70:    }while((nAccount1+nAccount2)==0 && nLoop < MAXLOOP);  
71:  
72:    return 0;  
73:}  

结果输出
第二部分结果分析
结果分析:
考虑到我们设定的NLoop上限为10000,可以看出最后程序nLoop准确地按照设定循环次数停了下了。Peterson算法实现成功。

5.4. 实验第三部分 Windows同步机制

74:#define MAXLOOP 10000  
75:int nAccount1 = 0;  
76:int nAccount2 = 0;  
77:  
78:HANDLE hMutex = CreateMutex(NULL, FALSE, "MutexToProtectCriticalResource");  
79:int nLoop = 0;  
80:DWORD WINAPI ThreadExecuteZZW(LPVOID lpParameter){  
81:    int *pID = (int *)lpParameter;  
82:    int nTemp1, nTemp2, nRandom;  
83:  
84:    do{  
85:        WaitForSingleObject(hMutex, INFINITE);  
86:        if(nLoop%1000 == 0){  
87:            cout << "thread "<< *pID << " is called " << "nLoop is "<< nLoop << "\n";  
88:        }  
89:        nRandom = rand();  
90:        nTemp1 = nAccount1;  
91:        nTemp2 = nAccount2;  
92:        nAccount1 = nTemp1 + nRandom;  
93:        nAccount2 = nTemp2 - nRandom;  
94:        ++nLoop;  
95:        ReleaseMutex(hMutex);  
96:  
97:    }while((nAccount1+nAccount2)==0 && nLoop < MAXLOOP);  
98:  
99:    return 0;  
100:}  

Windows Api 互斥信号量同步机制输出结果
通过结果来看,实验完成的非常好,进行地非常好。

5.5. 第四部分 Peterson和windows mutex同步机制效率比对

在这里插入图片描述
peterson算法和windows mutex的效率比较
上边为peterson算法,时间为0.015s;后边的是通过api调用mutex互斥变量进行同步的结果,用时0.046s。两个实验设置循环次数为10000次。
结论是Peterson算法效率更高。

(后按:这一点的结论很容易被老师用来判断是否是自己独立完成实验 2023年10月18日10:02:25)

6. 实验汇总

6.1. 实验要求完成情况

成功完成实验要求。

6.2. 技术难点及解决方案

Peterson 算法部分。一开始输出冲突,后来发现是输出语句的位置在标志之外,没有被同步机制管控,遂修改。后边的结果非常整齐。修改前的结果类似无同步机制。
在效率对比部分之前,一直使用sleep函数进行主线程等待子线程,后来在计算时间时发现这样只会计算主线程时间,从而无法比较。后来仔细查看实验指导发现可以采用WaitForMultipleObjects函数进行主线程等待,这样直接就可以得到子线程运行的时间了。

6.3. 实验感想和经验总结

本次实验主要是对课堂上所讲述的部分同步算法的一个实践,并且以windows平台作为代码编程环境api对象实践。掌握了许多windows的api同步函数,对同步的机制有了更深的理解。
关于实验中peterson算法的效率比windows自带的mutex api效率更高的结果,是出乎我的意料的。后来思考可能mutex调用系统的函数,里面有许多安全策略需要满足,速度自然打了折扣,如果按照简单实现的话,mutex其实可以就是一个bool型变量,那么效率应该和peterson算法在本实验中的结果不相上下,甚至更快。(peterson算法有三个控制变量,而按上述实现mutex法只有一个)

6.4. 参考链接

  • ZGSOS操作系统实验指导《实验课题5_同步机制及应用编程实现与比较》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值