操作系统多线程编程读者优先/写者优先详解

网友投稿 1050 2022-05-29

操作系统之进程调度——优先权法和轮转法(附上样例讲解)

操作系统之银行家算法—详解流程及案例数据

操作系统之多线程编程—读者优先/写者优先详解

操作系统之存储管理——FIFO算法和LRU算法

操作系统之磁盘调度——SCAN实例讲解

要求

一、实验目的

1、熟悉多线程编程

2、熟悉使用信号量机制解决进程同步问题

二、实验内容

创建一个包含n 个线程的控制台进程。用这n 个线程来表示n个读者或写者。每个线程按相应测试数据文件的要求,进行读写操作。请用信号量机制分别实现读者优先和写者优先的读者-写者问题。

读者优先:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。

写者优先:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。

三、实验条件

1、为每个学生提供一台具有WINDOWS 2000/NT/XP操作系统的计算机;

2、实验机器要求安装Visual C 6.0编程平台;

3、实验要求一人一机。

四、 运行结果显示要求

1、要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。

2、测试数据文件格式:测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各字段间用空格分隔。第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R 表示读者是,W 表示写者。第三字段为一个正数,表示读写操作的开始时间。线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。下面是一个测试数据文件的例子:

1 R 3 5

2 W 4 5

3 R 5 2

4 R 6 5

理解

上面是实验要求。下面讲讲自己的体会:

首先要明白在多线程编程中的互斥关系——读写互斥,写写互斥。两个优先方式都遵从这个出发点。

在满足以上的条件下,进来的线程都好像是在排队,然后看当前谁优先。

自己如果是优先的,那么可以直接插队。再考虑正在执行的是否和自己阻塞,如果正在执行的和自己阻塞,那自己也得排队,只不过排在前面。(类似写者优先的写写线程)如果正在执行的和自己不是阻塞的,那么自己就可以直接进去执行(读者优先的读读进程)。

如果自己不是优先的,那么自己只能老老实实的排队,就算自己前面有和自己不互斥的线程执行也不行。类似写者优先的(读线程在执行,新的写进程等待资源,更新的读线程只能等写进程释放,如果有新的写进程进来,还可以插队,——他只能等待队列中所有在等待的写进程释放完毕再执行自己。)

对于读者优先 :

读者就是优先的。假设a,b都是同时请求,但是a是读者那么a优先使用资源,还有一点很重要的就是读者优先的读者可以并行执行。而写着只能单线程执行。在执行过程中,只要阻塞的写者在等待过程中有新的读者进来那么他要等待所有读者完成才能自己释放自己。

对于写者优先:

无疑所有写的操作是优先的,这个过程可能会产生大量阻塞,因为相对较快(本来可以并行的读者被大量阻塞)。如果资源中没有写者那么读者依然可以并行,但是一旦出现写者在等待读者资源,那么新的读者就不能在并行执行,要等待所有写者执行完毕才可执行读者。

对于多线程编程的注意点有:

读者优先和写者优先是两个不同的策略方法,方法有相似之处但是也有很大不同,函数需要分开完成。

最主要的排序方式基于时间排序,次要的排序以读者还是写者谁优先为准则

读者优先或者写者优先的阻塞会导致线程开始时间的变化。而不过采用双队列一个存进入时间的排序,一个存结束时间的排序,修改其中的一个会影响另一个队列中元素值不错,但是如果不对另一个队列进行增/删是不会触发堆排序的功能(挺重要的)。

可能有些阻塞时候的等待时间和开始时间改变处理比较复杂,要考虑当前是读致使阻塞,还是写致使阻塞,还是前面有写的资源再等待致使阻塞。要用多个变量维系系统使得正确的更改线程的阻塞时间。

我的大体思路(水平有限,不一定很准确):

代码

下面附上我的ac代码

package 实验; import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; import java.util.Scanner; public class morethread { static Scanner sc=new Scanner(System.in); static Queueq1; static Queueend; static thread thread[]; static int time=0; private static void threadcreate(int n) {//创建线程 thread=new thread[n]; for(int i=0;i(comstart2); end=new PriorityQueue(comend); for(int i=0;i=writendtime)//没有写操作在前面 { if(team.starttimetimeend)//如果可以更新时间 { timeend=team.starttime+team.totaltime; } } } } } else { thread team=end.poll(); System.out.println("线程"+team.id+" 结束:"+team.type+" 结束时间"+(team.starttime+team.totaltime)); } } } private static void readerthread(int n)//读者优先 { q1=new PriorityQueue(comstart); end=new PriorityQueue(comend); for(int i=0;istart.starttime)//此时有写的情况,需要等待阻塞,也就是将此队列头抛出修改开始时间然后再次入队 { team.starttime=writendtime; q1.add(team); end.remove(team);end.add(team); } else {//此时无写的操作,无操作或者读操作 //System.out.println("线程"+team.id+" 开始:"+team.type+"操作 时间:"+team.starttime+" 结束时间"+(team.starttime+team.totaltime)); if(team.type.equals("w"))//写的情况,写需要检查是否阻塞自己如果有读的情况则需要阻塞自己 { int time2=timeend; if(time2=time2)//在这个时间前没有任何读或者写的操作,上锁,等于号一定有,因为都抛出它了,他的优先级一定最高 { writendtime=team.starttime+team.totaltime; System.out.println("线程"+team.id+" 开始:"+team.type+"操作 时间:"+team.starttime+" 结束时间"+(team.starttime+team.totaltime)); } else {//状态还有读操作,需要阻塞 team.starttime=time2; q1.add(team); end.remove(team);end.add(team); } } else//读的情况 { System.out.println("线程"+team.id+" 开始:"+team.type+"操作 时间:"+team.starttime+" 结束时间"+(team.starttime+team.totaltime)); if(team.starttime+team.totaltime>timeend) { timeend=team.starttime+team.totaltime; } } } } else if(!end.isEmpty()){//某个结束操作在这个时间段 thread team=end.poll(); System.out.println("线程"+team.id+" 结束:"+team.type+" 结束时间"+(team.starttime+team.totaltime)); } } } public static void main(String[] args) { System.out.println("请输入n个线程程序"); int n=sc.nextInt(); threadcreate(n); System.out.println("请输入数字选择读者优先或者写者优先\n1:读者优先\n2:写者优先"); int index=sc.nextInt(); while(index<1||index>2) {System.out.println("请输入正确的数字");index=sc.nextInt();} if(index==1)//读者优先 { readerthread(n); } else { writerthread(n); } } static Comparatorcomstart=new Comparator() {//读者优先的comparator接口,优先时间,时间相同则先返回 public int compare(thread o1, thread o2) { // TODO 自动生成的方法存根 if(o1.starttime==o2.starttime) { return (int)(o1.type.charAt(0)-o2.type.charAt(0));// r w 先r后w } else return o1.starttime-o2.starttime;//返回小根堆 } }; static Comparatorcomstart2=new Comparator() {//写者优先的 public int compare(thread o1, thread o2) { // TODO 自动生成的方法存根 if(o1.starttime==o2.starttime) { return (int)(o2.type.charAt(0)-o1.type.charAt(0));// w r 先w后r } else return o1.starttime-o2.starttime;//返回小根堆 } }; static Comparatorcomend=new Comparator() { public int compare(thread o1, thread o2) { return (int)((o1.starttime+o1.totaltime)-(o2.starttime+o2.totaltime)); } }; static class thread { int id; String type; int starttime; int totaltime; public thread(int id,String type,int starttime,int totaltime) { this.id=id; this.type=type; this.starttime=starttime; this.totaltime=totaltime; } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

操作系统之多线程编程—读者优先/写者优先详解

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

测试用例:

读者优先:

写者优先:

本人水平有限,?,如果有大佬发现错了,请指正。

如果对后端、爬虫、数据结构算法等感性趣欢迎关注我的个人公众号交流:bigsai

任务调度 多线程

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:面试官让手写队列,差点没写出来
下一篇:C语言真的很难吗?那是你没看这张图,化整为零轻松学习C语言。
相关文章