Thread lock && Mutex && event (processing critical section)

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;
}


Insert picture description here

to sum up:

  1. Thread lock can only be used for thread control between a single process
  2. 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;
}


Insert picture description here

Insert picture description here

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;
}

Insert picture description here
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.
Insert picture description here

CreateMutex return value:

  1. If the current function succeeds, the return value is a handle to a mutex
  2. 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)
  3. If the function fails, the return value is empty

The difference between mutex and thread lock:

  1. Thread lock can only be used for thread control between a single process
  2. The mutex can be set to wait for a timeout, but the thread lock cannot
  3. When the thread terminates unexpectedly, you Mutexcan 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.
  4. MutexEfficiency 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;

bManualResetIs it a notification type

bInitialStateIs there a signal? If
there is a signal , you can use WaitForSingleObjectit to get it; otherwise, it WaitForSingleObjectwill always be in a waiting state when calling ( FALSErepresenting 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;
}


Insert picture description here

Guess you like

Origin blog.csdn.net/CSNN2019/article/details/113903759