没有合适的资源?快使用搜索试试~ 我知道了~
首页Multithreading_Programming_-_Thread_Synchronization_c++
Multithreading_Programming_-_Thread_Synchronization_c++
需积分: 13 7 下载量 154 浏览量
更新于2023-03-03
评论
收藏 81KB PDF 举报
In the last chapter, we described several synchronization objects for multithreaded programming. For correct concurrent programs, multiple threads of execution must be synchronized to protect the integrity of shared data. In this chapter, we illustrate basic synchronization techniques using some classic concurrency problems of producer-consumer, bounded-buffer, and readers-writers.
资源详情
资源评论
资源推荐
53
CHAPTER
Thread Synchronization
I
n the last chapter, we described several synchro-
nization objects for multithreaded programming. For correct concurrent programs, multiple
threads of execution must be synchronized to protect the integrity of shared data. In this chap-
ter, we illustrate basic synchronization techniques using some classic concurrency problems
of
producer-consumer, bounded-buffer,
and
readers-writers.
3.1 The Producer-Consumer Problem
In the last chapter, we saw the simplest form of mutual exclusion: before accessing
shared data, each thread acquires ownership of a synchronization object. Once the thread has
finished accessing the data, it relinquishes the ownership so that other threads can acquire the
synchronization object and access the same data. Therefore, when accessing shared data,
each thread excludes all others from accessing the same data.
This simple form of mutual exclusion, however, is not enough for certain classes of
applications where designated threads are
producers
and
consumers
of data. The producer
threads write new values, while consumer threads read them. An analogy of the producer-
3
54 Chap. 3 Thread Synchronization
consumer situation is illustrated in Figure 3-1, where each thread,
producer
and
consumer
, is
represented by a robot arm. The producer picks up a box and puts it on a pedestal (shared
buffer) from which the consumer can pick it up. The consumer robot picks up boxes from the
pedestal for delivery. If we just use the simple synchronization technique of acquiring and
relinquishing a synchronization object, we may get incorrect behavior. For example, the pro-
ducer may try to put a block on the pedestal when there is already a block there. In such a
case, the newly produced block will fall off the pedestal.
To illustrate this situation in a multithreaded program, we present an implementation of
a producer-consumer situation with only mutual exclusion among threads.
1 #include <iostream.h>
2 #include <windows.h>
3
4 int SharedBuffer;
5 HANDLE hMutex;
6
7 void Producer()
8{
9 int i;
10
11 for (i=20; i>=0; i--) {
12 if (WaitForSingleObject(hMutex,INFINITE) == WAIT_FAILED){
13 cerr << "ERROR: Producer()" << endl;
14 ExitThread(0);
15 }
16 // got Mutex, begin critical section
17 cout << "Produce: " << i << endl;
18 SharedBuffer = i;
19 ReleaseMutex(hMutex); // end critical section
20 }
21 }
22
23
24 void Consumer()
25 {
26 int result;
Figure 3-1
.
An Illustrative Analogy for the Producer-Consumer Problem.
P
C
Producer
Consumer
Mutex Lock
Shared
Space
3.1 The Producer-Consumer Problem 55
27
28 while (1) {
29 if (WaitForSingleObject(hMutex,INFINITE) == WAIT_FAILED){
30 cerr << "ERROR: Producer" << endl;
31 ExitThread(0);
32 }
33 if (SharedBuffer == 0) {
34 cout << "Consumed " << SharedBuffer << ": end of data" << endl;
35 ReleaseMutex(hMutex); // end critical section
36 ExitThread(0);
37 }
38
39 // got Mutex, data in buffer, start consuming
40 if (SharedBuffer > 0){ // ignore negative values
41 result = SharedBuffer;
42 cout << "Consumed: " << result << endl;
43 ReleaseMutex(hMutex); // end critical section
44 }
45 }
46 }
47
48 void main()
49 {
50 HANDLE hThreadVector[2];
51 DWORD ThreadID;
52
53 SharedBuffer = -1;
54 hMutex = CreateMutex(NULL,FALSE,NULL);
55
56 hThreadVector[0]= CreateThread(NULL,0,
57 (LPTHREAD_START_ROUTINE)Producer,
58 NULL, 0, (LPDWORD)&ThreadID);
59 hThreadVector[1]=CreateThread(NULL,0,
60 (LPTHREAD_START_ROUTINE)Consumer,
61 NULL, 0, (LPDWORD)&ThreadID);
62 WaitForMultipleObjects(2,hThreadVector,TRUE,INFINITE);
63 // process ends here
64 }
65
This program creates two threads,
Producer
and
Consumer,
which exchange data using
a shared variable, named
SharedBuffer
. All access to
SharedBuffer
must be from
within a critical section. The program serializes access to the
SharedBuffer
, guaranteeing
that concurrent accesses by producer and consumer threads will not corrupt the data in it. A
sample output from a random run of the program is:
1. Produce: 20 16. Produce: 9
2. Consumed: 20 17. Produce: 8
3. Produce: 19 18. Produce: 7
4. Consumed: 19 19. Produce: 6
5. Produce: 18 20. Produce: 5
6. Produce: 17 21. Produce: 4
7. Produce: 16 22. Produce: 3
56 Chap. 3 Thread Synchronization
8. Produce: 15 23. Produce: 2
9. Produce: 14 24. Consumed: 2
10. Produce: 13 25. Consumed: 2
11. Produce: 12 26. Consumed: 2
12. Produce: 11 27. Consumed: 2
13. Consumed: 11 28. Produce: 1
14. Consumed: 11 29. Consumed: 1
15. Produce: 10 30. Consumed 0: end of data
As we can see, something is wrong: not every value produced by the producer is con-
sumed, and sometimes the same value is consumed many times. The intended behavior is that
the producer and consumer threads alternate in their access to the shared variable. We do not
want the producer to overwrite the variable before its value is consumed; nor do we want the
consumer thread to use the same value more than once.
The behavior occurs because mutual exclusion alone is not sufficient to solve the pro-
ducer-consumer problem—we need both mutual exclusion and synchronization among the
producer and consumer threads.
In order to achieve synchronization, we need a way for each thread to communicate
with the others. When a producer produces a new value for the shared variable, it must inform
the consumer threads of this event. Similarly, when a consumer has read a data value, it must
trigger an event to notify possible producer threads about the empty buffer. Threads receiving
such event signals can then gain access to the shared variable in order to produce or consume
more data. Figure 3-2 shows our producer and consumer robots with added event signals.
The next program uses two event objects, named
hNotEmptyEvent
and
hNot-
FullEvent
, to synchronize the producer and the consumer threads.
1 #include <iostream.h>
2 #include <windows.h>
3
4 #define FULL 1
5 #define EMPTY 0
Figure 3-2
.
The Producer and Consumer Robots with Synchronization.
Mutex Lock
NotEmpty
NotFull
Producer
Consumer
P
C
Shared
Space
3.1 The Producer-Consumer Problem 57
6
7 int SharedBuffer;
8 int BufferState;
9 HANDLE hMutex;
10 HANDLE hNotFullEvent, hNotEmptyEvent;
11
12 void Producer()
13 {
14 int i;
15
16 for (i=20; i>=0; i--) {
17 while(1) {
18 if (WaitForSingleObject(hMutex,INFINITE) == WAIT_FAILED){
19 cerr << "ERROR: Producer()" << endl;
20 ExitThread(0);
21 }
22 if (BufferState == FULL) {
23 ReleaseMutex(hMutex);
24 // wait until buffer is not full
25 WaitForSingleObject(hNotFullEvent,INFINITE);
26 continue; // back to loop to test BufferState again
27 }
28 // got mutex and buffer is not FULL, break out of while loop
29 break;
30 }
31
32 // got Mutex, buffer is not full, producing data
33 cout << "Produce: " << i << endl;
34 SharedBuffer = i;
35 BufferState = FULL;
36 ReleaseMutex(hMutex); // end critical section
37 PulseEvent(hNotEmptyEvent); // wake up consumer thread
38 }
39 }
40
41 void Consumer()
42 {
43 int result;
44
45 while (1) {
46 if (WaitForSingleObject(hMutex,INFINITE) == WAIT_FAILED){
47 cerr << "ERROR: Producer()" << endl;
48 ExitThread(0);
49 }
50 if (BufferState == EMPTY) { // nothing to consume
51 ReleaseMutex(hMutex); // release lock to wait
52 // wait until buffer is not empty
53 WaitForSingleObject(hNotEmptyEvent,INFINITE);
54 continue; // return to while loop to contend for Mutex again
55 }
56
57 if (SharedBuffer == 0) { // test for end of data token
58 cout << "Consumed " << SharedBuffer << ": end of data" << endl;
59 ReleaseMutex(hMutex); // end critical section
剩余24页未读,继续阅读
dongdongnidenao
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 2022年中国足球球迷营销价值报告.pdf
- 房地产培训 -营销总每天在干嘛.pptx
- 黄色简约实用介绍_汇报PPT模板.pptx
- 嵌入式系统原理及应用:第三章 ARM编程简介_3.pdf
- 多媒体应用系统.pptx
- 黄灰配色简约设计精美大气商务汇报PPT模板.pptx
- 用matlab绘制差分方程Z变换-反变换-zplane-residuez-tf2zp-zp2tf-tf2sos-sos2tf-幅相频谱等等.docx
- 网络营销策略-网络营销团队的建立.docx
- 电子商务示范企业申请报告.doc
- 淡雅灰低面风背景完整框架创业商业计划书PPT模板.pptx
- 计算模型与算法技术:10-Iterative Improvement.ppt
- 计算模型与算法技术:9-Greedy Technique.ppt
- 计算模型与算法技术:6-Transform-and-Conquer.ppt
- 云服务安全风险分析研究.pdf
- 软件工程笔记(完整版).doc
- 电子商务网项目实例规划书.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0