跳至主要内容

12.事件

通知类型

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
#include <handleapi.h>
#include <minwindef.h>
#include <processthreadsapi.h>
#include <stdio.h>
#include <synchapi.h>
#include <windows.h>
#include <winnt.h>

HANDLE g_hEvent;

DWORD WINAPI ThreadProc_1 (LPVOID lsParameter){
WaitForSingleObject(g_hEvent, INFINITE);
printf("ThreadProc_1\n");
getchar();
return 0;
}

DWORD WINAPI ThreadProc_2 (LPVOID lsParameter){
WaitForSingleObject(g_hEvent, INFINITE);
printf("ThreadProc_2\n");
getchar();
return 0;
}

int main(int argc, char *argv[]) {
//第二个参数TRUE为通知类型,FALSE为互斥
g_hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
HANDLE hThread[2];
hThread[0] = CreateThread(NULL, 0, ThreadProc_1, NULL, 0, NULL);
hThread[1] = CreateThread(NULL, 0, ThreadProc_2, NULL, 0, NULL);

SetEvent(g_hEvent);

WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
return 0;
}

线程同步

  • 线程互斥:线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排他性。当有若干个线程都要使用某一个共享资源时,任何时刻最多只允许一个线程去使用,其他要使用该资源的线程必须等待,直到占用资源者释放该资源。
  • 线程同步:线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,知道消息到达时才被唤醒。
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
假有序
#include <handleapi.h>
#include <minwindef.h>
#include <processthreadsapi.h>
#include <stdio.h>
#include <synchapi.h>
#include <windef.h>
#include <windows.h>
#include <winnt.h>

HANDLE hMutex;
int g_Max = 10;
int g_Number = 0;
DWORD WINAPI ThreadProduct(LPVOID lsParameter){
for (int i = 0; i < g_Max; i++) {
if(g_Number == 0){
WaitForSingleObject(hMutex, INFINITE);
g_Number = 1;
DWORD id = GetCurrentThreadId();
printf("生产者%lx将数据%d放入缓存区\n",id,g_Number);
ReleaseMutex(hMutex);
}else {
printf("浪费时间\n");
i--;
}
}
return 0;
}

DWORD WINAPI ThreadConsumer(LPVOID lsParameter){
for (int i = 0; i < g_Max; i++) {
if(g_Number == 1){
WaitForSingleObject(hMutex, INFINITE);
g_Number = 0;
DWORD id = GetCurrentThreadId();
printf("消费者%lx将数据%d放入缓存区\n",id,g_Number);
ReleaseMutex(hMutex);
}else {
printf("浪费时间\n");
i--;
}

}
return 0;
}

int main(int argc, char *argv[]) {
hMutex = CreateMutexA(NULL, FALSE, NULL);
HANDLE aThread[2];
aThread[0] = CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
aThread[1] = CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);

WaitForMultipleObjects(2, aThread, TRUE, INFINITE);
CloseHandle(aThread[0]);
CloseHandle(aThread[1]);
return 0;
}

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
真有序
#include <handleapi.h>
#include <minwindef.h>
#include <processthreadsapi.h>
#include <stdio.h>
#include <synchapi.h>
#include <windef.h>
#include <windows.h>
#include <winnt.h>

int g_Max = 10;
int g_Number = 0;
HANDLE hE;
HANDLE hD;
DWORD WINAPI ThreadProduct(LPVOID lsParameter){
for (int i = 0; i < g_Max; i++) {
WaitForSingleObject(hE, INFINITE);
g_Number = 1;
DWORD id = GetCurrentThreadId();
printf("生产者%lx将数据%d放入缓存区\n",id,g_Number);
SetEvent(hD);
}
return 0;
}

DWORD WINAPI ThreadConsumer(LPVOID lsParameter){
for (int i = 0; i < g_Max; i++) {
WaitForSingleObject(hD, INFINITE);
g_Number = 0;
DWORD id = GetCurrentThreadId();
printf("消费者%lx将数据%d放入缓存区\n",id,g_Number);
SetEvent(hE);

}
return 0;
}

int main(int argc, char *argv[]) {
HANDLE aThread[2];
hE = CreateEventA(NULL, FALSE, TRUE, NULL);
hD = CreateEventA(NULL, FALSE, FALSE, NULL);
aThread[0] = CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
aThread[1] = CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);



WaitForMultipleObjects(2, aThread, TRUE, INFINITE);
CloseHandle(aThread[0]);
CloseHandle(aThread[1]);
CloseHandle(hD);
CloseHandle(hE);
return 0;
}

关于本文

由 GuQing 撰写,采用 CC BY-NC 4.0 许可协议。