Win32_2-线程控制--临界区&互斥体

临界区

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //

    LONG LockCount;             //初始化为数值-1,此数值等于或者大于0时,表示此临界区被占用
    							//等待获得临界区的线程数:LockCount-(RecursionCount-1)
    LONG RecursionCount;        //此字段包含所有线程已经获得该临界区的次数
    HANDLE OwningThread;        //占用此临界区的线程的线程标识符,此线程ID与GetCurrentThreadId所返回的ID相同
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;//简化的宏定义

Win32_2-线程控制--临界区&互斥体

使用以下代码创建临界区,并且初始化:

CRITICAL_SECTION cs;                   //创建临界区
InitializeCriticalSection(&cs);        // 初始化临界区

进入临界区和离开

EnterCriticalSection(&cs);
LeaveCriticalSection(&g_cs); 

释放临界区

VOID DeleteCriticalSection(PCRITICAL_SECTION pcs);

Win32_2-线程控制--临界区&互斥体一个简单使用临界区的例子

#include <iostream>
#include <windows.h>
CRITICAL_SECTION cs;
int a = 0;
HANDLE ht1; HANDLE ht2;
DWORD WINAPI ThreadPorc1(LPVOID  lpParameter)
{
	for (int i = 0; i < 100; i++)
	{
		EnterCriticalSection(&cs);
		a++;
		printf("线程1对a进行读写--%d\n", a);
		LeaveCriticalSection(&cs);
		Sleep(100);
	}
	
	return 0;
}

DWORD WINAPI ThreadPorc2(LPVOID  lpParameter)
{
	for (int i = 0; i < 100; i++)
	{
		EnterCriticalSection(&cs);
		a++;
		printf("线程2对a进行读写--%d\n", a);
		LeaveCriticalSection(&cs);
		Sleep(100);
	}
	return 0;
}
int main()
{
	InitializeCriticalSection(&cs);
	HANDLE ht1 = ::CreateThread(NULL, 0, ThreadPorc1, NULL, 0, NULL);
	HANDLE ht2 = ::CreateThread(NULL, 0, ThreadPorc2, NULL, 0, NULL);
	::WaitForSingleObject(ht1, INFINITE); ::CloseHandle(ht1);
	::WaitForSingleObject(ht2, INFINITE); ::CloseHandle(ht2);
	
	return 0;
}

等待内核对象

DWORD WaitForSingleObject(
	HANDLE hHandle,        // 内核对象句柄,可以是进程也可以是线程.
	DWORD dwMilliseconds   // 等待时间,单位是毫秒  INFINITE(-1)一直等待		
);

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止.

1、内核对象中的每种对象都可以说是处于已通知或未通知的状态之中

2、这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的

3、当线程正在运行的时候,线程内核对象处于未通知状态

4、当线程终止运行的时候,它就变为已通知状态

5、在内核中就是个BOOL值,运行时FALSE 结束TRUE

//创建一个新的线程				
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,NULL, 0, NULL);
::WaitForSingleObject(hThread1, INFINITE); //当线程 hThread1  执行完毕以后
->执行代码

DWORD WaitForMultipleObjects(
	DWORD nCount,             //要查看内核对象的数量
	CONST HANDLE *lpHandles,  //内核对象数组	
	BOOL bWaitAll,            //等到类型  TRUE 等到所有变为已通知  FALSE 只要有一个变为已通知				
	DWORD dwMilliseconds      // 等待时间,单位是毫秒  INFINITE(-1)一直等待						
);
HANDLE hArray[2];			
HANDLE hArray[0]= ::CreateThread(NULL, 0, ThreadProc1,NULL, 0, NULL);
HANDLE hArray[1]= ::CreateThread(NULL, 0, ThreadProc2,NULL, 0, NULL);
DWORD dwCode = ::WaitForMultipleObjects(2, hArray, FALSE, INFINITE);
->执行代码

互斥体

HANDLE CreateMutexA(  				           //跨进程
  LPSECURITY_ATTRIBUTES lpMutexAttributes,     //使用互斥的权限,只读等待
  BOOL                  bInitialOwner,		   //是否可继承
  LPCSTR                lpName                 //标识符号名字
);

创建互斥体

HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");
HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "XYZ");

WaitForSingleObject(g_hMutex, INFINITE);

//逻辑代码1

ReleaseMutex(g_hMutex);

HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "XYZ");

WaitForSingleObject(g_hMutex, INFINITE);

//逻辑代码2

ReleaseMutex(g_hMutex);
#include <iostream>
#include <windows.h>
HANDLE g_hMutex = CreateMutex(NULL, FALSE, L"XYZ");
int a = 0;
HANDLE hArray[2];
DWORD WINAPI ThreadPorc1(LPVOID  lpParameter)
{
	for (int i = 0; i < 100; i++)
	{
		HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"XYZ");
		WaitForSingleObject(g_hMutex, INFINITE);
		a++;
		printf("线程1对a进行读写--%d\n", a);
		ReleaseMutex(g_hMutex);
		Sleep(100);
	}
	
	return 0;
}

DWORD WINAPI ThreadPorc2(LPVOID  lpParameter)
{
	for (int i = 0; i < 100; i++)
	{
		HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"XYZ");
		WaitForSingleObject(g_hMutex, INFINITE);
		a++;
		printf("线程2对a进行读写--%d\n", a);
		ReleaseMutex(g_hMutex);
		Sleep(100);
	}
	return 0;
}
int main()
{
	hArray[0] = ::CreateThread(NULL, 0, ThreadPorc1, NULL, 0, NULL);
	hArray[1] = ::CreateThread(NULL, 0, ThreadPorc2, NULL, 0, NULL);
	DWORD dwCode = ::WaitForMultipleObjects(2, hArray, FALSE, INFINITE);
	return 0;
}

Win32_2-线程控制--临界区&互斥体