Windows系统——多线程互斥访问临界资源
Windows系统——多线程互斥访问临界资源
实现代码
/*
author : eclipse
email : eclipsecs@qq.com
time : Fri Apr 24 15:45:42 2020
*/
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;CRITICAL_SECTION mutex;
const int THREAD_NUM = 5;
int value = 25;DWORD CALLBACK print(LPVOID param) {for (int i = 0; i < 5; i++) {EnterCriticalSection(&mutex);printf("%d\n", value--);LeaveCriticalSection(&mutex);}return 0;
}int main(int argc, char const *argv[])
{InitializeCriticalSection(&mutex);DWORD threadId[THREAD_NUM];HANDLE threadHandle[THREAD_NUM];for (int i = 0; i < THREAD_NUM; i++) {if (!(threadHandle[i] = CreateThread(NULL, 0, print, NULL, 0, &threadId[i]))) {printf("Thread create error!\n");abort();}}WaitForMultipleObjects(THREAD_NUM, threadHandle, true, INFINITE);DeleteCriticalSection(&mutex);return 0;
}
临界资源
- 临界资源
临界资源指的是允许仅允许一个线程(进程)在一个时间段使用的资源,例如外设、一些共享变量等,多个线程必须互斥访问临界资源 - 初始化临界区
WINBASEAPI
VOID
WINAPI
InitializeCriticalSection(_Out_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 进入区
WINBASEAPI
VOID
WINAPI
EnterCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 临界区
临界区指的是访问临界资源的那一段代码 - 退出区
WINBASEAPI
VOID
WINAPI
LeaveCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 删除临界区
WINBASEAPI
VOID
WINAPI
DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
- 功能
上述函数保证多线程能够互斥地访问临界资源,上述实现中多线程互斥地访问共享全局变量value,当一个线程进入临界区后,其他试图进入临界区的线程将被阻塞,直到进入临界区的线程离开临界区 - 临界区调度准则
- 空闲让进
- 忙则等待
- 有限等待
- 让权等待
注意
- 互斥访问临界资源
若在上述实现中注释掉 EnterCriticalSection()函数和LeaveCriticalSection()函数,则不能保证多线程互斥地访问临界资源,多线程同时访问共享全局变量value,将造成意料之外的结果,输出顺序被打乱
25
22
19
18
17
16
23
15
14
13
12
24
11
10
21
8
7
6
9
5
20
4
3
2
1
输出结果
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!
Windows系统——多线程互斥访问临界资源
Windows系统——多线程互斥访问临界资源
实现代码
/*
author : eclipse
email : eclipsecs@qq.com
time : Fri Apr 24 15:45:42 2020
*/
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;CRITICAL_SECTION mutex;
const int THREAD_NUM = 5;
int value = 25;DWORD CALLBACK print(LPVOID param) {for (int i = 0; i < 5; i++) {EnterCriticalSection(&mutex);printf("%d\n", value--);LeaveCriticalSection(&mutex);}return 0;
}int main(int argc, char const *argv[])
{InitializeCriticalSection(&mutex);DWORD threadId[THREAD_NUM];HANDLE threadHandle[THREAD_NUM];for (int i = 0; i < THREAD_NUM; i++) {if (!(threadHandle[i] = CreateThread(NULL, 0, print, NULL, 0, &threadId[i]))) {printf("Thread create error!\n");abort();}}WaitForMultipleObjects(THREAD_NUM, threadHandle, true, INFINITE);DeleteCriticalSection(&mutex);return 0;
}
临界资源
- 临界资源
临界资源指的是允许仅允许一个线程(进程)在一个时间段使用的资源,例如外设、一些共享变量等,多个线程必须互斥访问临界资源 - 初始化临界区
WINBASEAPI
VOID
WINAPI
InitializeCriticalSection(_Out_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 进入区
WINBASEAPI
VOID
WINAPI
EnterCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 临界区
临界区指的是访问临界资源的那一段代码 - 退出区
WINBASEAPI
VOID
WINAPI
LeaveCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
参数lpCriticalSection为临界区指针
- 删除临界区
WINBASEAPI
VOID
WINAPI
DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);
- 功能
上述函数保证多线程能够互斥地访问临界资源,上述实现中多线程互斥地访问共享全局变量value,当一个线程进入临界区后,其他试图进入临界区的线程将被阻塞,直到进入临界区的线程离开临界区 - 临界区调度准则
- 空闲让进
- 忙则等待
- 有限等待
- 让权等待
注意
- 互斥访问临界资源
若在上述实现中注释掉 EnterCriticalSection()函数和LeaveCriticalSection()函数,则不能保证多线程互斥地访问临界资源,多线程同时访问共享全局变量value,将造成意料之外的结果,输出顺序被打乱
25
22
19
18
17
16
23
15
14
13
12
24
11
10
21
8
7
6
9
5
20
4
3
2
1
输出结果
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!
发布评论