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;//简化的宏定义
使用以下代码创建临界区,并且初始化:
CRITICAL_SECTION cs; //创建临界区
InitializeCriticalSection(&cs); // 初始化临界区
进入临界区和离开
EnterCriticalSection(&cs);
LeaveCriticalSection(&g_cs);
释放临界区
VOID DeleteCriticalSection(PCRITICAL_SECTION pcs);
一个简单使用临界区的例子
#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;
}