Article Directory
Thread lock
Thread lock implemented by critical section:
Create global variables:
CRITICAL_SECTION cs;
Initialize global variables:
InitializeCriticalSection(&cs);
Realize the critical section:
EnterCriticalSection(&cs);
//使用临界资源
LeaveCriticalSection(&cs);
Instance
#include <iostream>
#include<Windows.h>
//创建全局变量
CRITICAL_SECTION cs;
int a = 10;
void MyFirstThreadProc() {
EnterCriticalSection(&cs);
while (a > 0) {
a--;
printf("卖了一张,还有%d张票\n", a);
}
LeaveCriticalSection(&cs);
}
void MySecondThreadProc() {
EnterCriticalSection(&cs);
while (a > 0) {
a--;
printf("卖了一张,还有%d张票\n", a);
}
LeaveCriticalSection(&cs);
}
int main()
{
//初始化全局变量
InitializeCriticalSection(&cs);
HANDLE aThreadProc[2];
aThreadProc[1] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MyFirstThreadProc,
NULL,
0,
NULL
);
aThreadProc[2] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MySecondThreadProc,
NULL,
0,
NULL
);
system("pause");
return 0;
}
to sum up:
- Thread lock can only be used for thread control between a single process
- In the thread lock situation, if a thread terminates unexpectedly but does not release the token, then there is an infinite wait.
Mutex
Mutex for the realization of critical section:
Critical resource access across processes:
HANDLE CreateMutex()
Create a mutex (kernel object)
HANDLE g_hMutex=CreateMutex(NULL,FALSE,“xyz”)
“xyz”
: The name of the mutex
FALSE: If thereFALSE
is a signal (that is, it can be used directly );
if it is TRUE, it is no signal (that is, it cannot be used directly) (If TRUE is filled in, it means that the current
mutex belongs to the current process )
//There are two situations where the token can be obtained 1. There is a signal 2. The thread owner
Get the token:
WaitForSingleObject(g_hMutex,INFINITE)
Release token:
ReleaseMutex(g_hMutex)
Same process
#include <iostream>
#include<Windows.h>
int a = 10;
void MyFirstThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, TRUE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("A进程的x线程卖了一张,还有%d张票\n", a);
}
//释放令牌
ReleaseMutex(g_hMutex);
}
void MySecondThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, TRUE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("B进程的y线程卖了一张,还有%d张票\n", a);
}
//释放令牌
ReleaseMutex(g_hMutex);
}
int main()
{
HANDLE aThreadProc[2];
aThreadProc[1] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MyFirstThreadProc,
NULL,
0,
NULL
);
aThreadProc[2] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MySecondThreadProc,
NULL,
0,
NULL
);
system("pause");
return 0;
}
Different processes
Process 1 (In fact, I also added one getchar
):
#include <iostream>
#include<Windows.h>
int a = 10;
void MyFirstThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, TRUE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("A进程的x线程卖了一张,还有%d张票\n", a);
}
getchar();
//释放令牌
ReleaseMutex(g_hMutex);
}
void MySecondThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, TRUE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("B进程的y线程卖了一张,还有%d张票\n", a);
}
getchar();
//释放令牌
ReleaseMutex(g_hMutex);
}
int main()
{
HANDLE aThreadProc[2];
aThreadProc[1] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MyFirstThreadProc,
NULL,
0,
NULL
);
aThreadProc[2] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MySecondThreadProc,
NULL,
0,
NULL
);
system("pause");
return 0;
}
Process 2:
#include <iostream>
#include<Windows.h>
int a = 10;
void MyFirstThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, FALSE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("B进程的x线程卖了一张,还有%d张票\n", a);
}
//释放令牌
ReleaseMutex(g_hMutex);
}
void MySecondThreadProc() {
//创建一个互斥体
HANDLE g_hMutex = CreateMutex(NULL, FALSE, "xy");
//获取令牌
WaitForSingleObject(g_hMutex, INFINITE);
while (a > 0) {
a--;
printf("B进程的y线程卖了一张,还有%d张票\n", a);
}
//释放令牌
ReleaseMutex(g_hMutex);
}
int main()
{
HANDLE aThreadProc[2];
aThreadProc[1] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MyFirstThreadProc,
NULL,
0,
NULL
);
aThreadProc[2] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MySecondThreadProc,
NULL,
0,
NULL
);
system("pause");
return 0;
}
The execution of mutex 1 process is finished, but mutex 1 has not released the lock, so mutex 2 is impossible to execute, and then I press enter in mutex 1.
CreateMutex return value:
- If the current function succeeds, the return value is a handle to a mutex
- If the mutex with the same name already exists in the kernel, the CreateMutex function will also return a handle, and the return value happens to be the handle of the original mutex. (But at this time, the return value of GetlastError is ERROR_ALREADY_EXISTS)
- If the function fails, the return value is empty
The difference between mutex and thread lock:
- Thread lock can only be used for thread control between a single process
- The mutex can be set to wait for a timeout, but the thread lock cannot
- When the thread terminates unexpectedly, you
Mutex
can avoid infinite waiting; in the thread lock situation, if a thread terminates unexpectedly, but does not release the token, then there is an infinite waiting situation. Mutex
Efficiency is not as high as thread lock
event
1. Notification type:
HANDLE CreatEvent(
LPSECURITY_ATTRIBUTES IpEventAttributes, //SD
BOOL bManualReset, //reset type
BOOL bInitialState, //initial state
LPCTSTR IpName //object name
);
bManualReset
Is it a notification type
bInitialState
Is there a signal? If
there is a signal , you can use WaitForSingleObject
it to get it; otherwise, it WaitForSingleObject
will always be in a waiting state when calling ( FALSE
representing no initial signal)
#include <iostream>
#include<Windows.h>
int a = 10;
HANDLE g_event;
void MyFirstThreadProc() {
SetEvent(g_event);//设置事件为已通知
WaitForSingleObject(g_event, INFINITE);
while (a > 0) {
a--;
printf("B进程的x线程卖了一张,还有%d张票\n", a);
}
}
void MySecondThreadProc() {
WaitForSingleObject(g_event, INFINITE);
while (a > 0) {
a--;
printf("B进程的y线程卖了一张,还有%d张票\n", a);
}
}
int main()
{
g_event = CreateEvent(NULL, FALSE, FALSE, NULL);
//第二个参数FALSE表示是否是通知类型,何为通知类型呢?也就是群发,A收到后,不会被改变它的状态;如果不是通知类型的话,那么A
//收到之后就会改变它的状态,然后B执行WaitForSingleObject不能成功。
//第三个参数表示是否有信号,TRUE为有信号,FALSE为无信号
HANDLE aThreadProc[2];
aThreadProc[1] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MyFirstThreadProc,
NULL,
0,
NULL
);
aThreadProc[2] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)MySecondThreadProc,
NULL,
0,
NULL
);
// SetEvent(g_event);//设置事件为已通知
system("pause");
return 0;
}