线程锁

/*
Mutex和critical的区别:
Mutex较慢。 Mutex 是内核对象,相关函数的执行 (WaitForSingleObject, ReleaseMutex)需要用户模式(User Mode)到内核模
式(Kernel Mode)的转换,在x86处理器上这种转化一般要发费600个左右的 CPU指令周期。
 
critical较快。Critical Section本身不是内核对象,相关函数(EnterCriticalSection,LeaveCriticalSection)的调用一般都在
用户模式内执行,在x86处理器上一般只需要发费9个左右的 CPU指令周期。只有当想要获得的锁正好被别的线程拥有时才会退化成和
Mutex一样,即转换到内核模式,发费600个左右的 CPU指令周期。

1.当拥有锁的线程死亡时 ,Mutex变成abandoned状态,其他的等待线程可以获得锁。 Critical Section的状态不可知(undefined),
以后的动作就不能保证了。  

2.对已获得的Mutex,重复调用WaitForSingleObject不会锁住自己。但最后你别忘了要调用同样次数的ReleaseMutex,对已获得的
Critical Section,重复调用EnterCriticalSection不会锁住自己。但最后你别忘了要调用同样次数的LeaveCriticalSection) 

*/ 
/*函数原型:
HANDLE CreateMutex(

LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针

BOOL bInitialOwner, // 初始化互斥对象的所有者

LPCTSTRlpName // 指向互斥对象名的指针

);
*/
#include<windows.h>
#include<process.h>
#include<iostream>
using namespace std;
int a = 0;
//CRITICAL_SECTION g_cs;
HANDLE hmtx;
unsigned int _stdcall ThreadFunc(LPVOID lpa)
{
	for (int i = 0; i < 8; i++)
	{
	//EnterCriticalSection(&g_cs);
	WaitForSingleObject(hmtx, INFINITE);
	a++;
	cout<< "线程" << (int *)lpa << "的值为" << a /*<< " ,id为" << GetCurrentThreadId() */<< endl;
	//LeaveCriticalSection(&g_cs);
	ReleaseMutex(hmtx);
	Sleep(1000);
	}
	return 0;
}
int main(void)
{
	//InitializeCriticalSection(&g_cs);
	hmtx = CreateMutex(NULL, FALSE, NULL);
	HANDLE hHandle[2];
	hHandle[0] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc, (void *)(int)1,  0, NULL);
	hHandle[1] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc, (void *)(int)2, 0, NULL);
	while(1)
	{ 
		DWORD r;
		r = WaitForMultipleObjects(2, hHandle, TRUE, 1000);
		if (r != WAIT_OBJECT_0)
		{ 
			cout << "\nTIMEOUT\n";
			continue;
		}
		if (r == WAIT_OBJECT_0)
		{
			cout<<"\nWAIT_OBJECT_0\n";
			break;
		}
	}
	CloseHandle(hHandle[0]);
	CloseHandle(hHandle[1]);
	cout << "Close Handle" << endl;
	//DeleteCriticalSection(&g_cs);
	CloseHandle(hmtx);
	system("pause");
}

你可能感兴趣的:(线程锁)