多線程實現線程同步——互次對


原文地址:多線程實現線程同步——互次對象 - CSDN博客  http://blog.csdn.net/qq_25425023/article/details/45287071




多線程實現線程同步——互次對象


互次對象實現線程同步。

1.使用API函數操作互次對象。

函數CreateMutex用於創建並返回互次對象。

函數原型:

HANDLE CreateMutex(  LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD
  BOOL bInitialOwner,                       // initial owner
  LPCTSTR lpName                            // object name);

參數lpMutexAttributes指定新創建互次對象的安全屬性。如果該參數爲NULL,表示互次對象擁有默認安全屬性。

參數bInitialOwner表示該互次對象的擁有者。如果爲true,則表示創建該互次對象的線程擁有其所有權。如果爲false,表示創建的互次對象的線程不能擁有該互次對象的所有權。

參數lpName表示互次對象的名稱。若該參數爲NULL,則表示程序創建的是匿名對象,如果爲該參數指定值,則可以通過調用函數OpenMutex打開一個命名的互次對象。

調用函數ReleaseMutex釋放該對象的所有權,也就是讓該互次對象處於有信號狀態。

函數原型:

BOOL ReleaseMutex(  HANDLE hMutex   // handle to mutex);

下面是C語言實現的代碼:

#include <stdio.h>
#include <windows.h>

DWORD WINAPI myfun1(LPVOID lpParameter);                    //聲明線程函數
DWORD WINAPI myfun2(LPVOID lpParameter);

HANDLE hmutex;
int a = 0;

int main()
{
	hmutex = ::CreateMutex(NULL, FALSE, NULL);
	HANDLE h1, h2;
	h1 = ::CreateThread(NULL, 0, myfun1, NULL, 0, NULL);     //創建線程
	printf("線程1開始運行!\r\n");
	h2 = ::CreateThread(NULL, 0, myfun2, NULL, 0, NULL);
	printf("線程2開始運行!\r\n");
	::CloseHandle(h1);
	::CloseHandle(h2);
	::Sleep(10000);
	return 0;
}
DWORD WINAPI myfun1(LPVOID lpParameter)
{
	while(1)
	{
		::WaitForSingleObject(hmutex, INFINITE);             //請求互次對象
		if(a < 1000)
		{
			a += 1;
			::Sleep(1000);
			printf("線程1正在計數%d\r\n", a);
			::ReleaseMutex(hmutex);                          //釋放互次對象句柄
		}
		else
		{
			::ReleaseMutex(hmutex);
			break;
		}
	}
	return 0;
}
DWORD WINAPI myfun2(LPVOID lpParameter)
{
	while(1)
	{
		::WaitForSingleObject(hmutex, INFINITE);
		if(a < 1000)
		{
			a += 1;
			::Sleep(1000);
			printf("線程2正在計數%d\r\n", a);
			::ReleaseMutex(hmutex);
		}
		else
		{
			::ReleaseMutex(hmutex);
			break;
		}
	}
	return 0;
}



2.使用CMutex類


創建CMutex類對象是通過其構造函數實現的。

構造函數原型:

CMutex( BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL );


調用函數Lock和Unlock對該互次對象所保護的區域進行鎖定和解鎖。


代碼:

#include <stdio.h>
#include <afxmt.h>

DWORD WINAPI myfun1(LPVOID lpParameter);                    //聲明線程函數
DWORD WINAPI myfun2(LPVOID lpParameter);
CMutex hmutex(NULL, FALSE, NULL);
int a = 0;
int main()
{
	HANDLE h1, h2;
	h1 = ::CreateThread(NULL, 0, myfun1, NULL, 0, NULL);     //創建線程
	printf("線程1開始運行!\r\n");
	h2 = ::CreateThread(NULL, 0, myfun2, NULL, 0, NULL);
	printf("線程2開始運行!\r\n");
	::CloseHandle(h1);
	::CloseHandle(h2);
	::Sleep(10000);
	return 0;
}
DWORD WINAPI myfun1(LPVOID lpParameter)
{
	while(1)
	{
		hmutex.Lock(INFINITE);                            //鎖定互次對象
		if(a < 1000)
		{
			a += 1;
			::Sleep(1000);
			printf("線程1: %d\r\n", a);
			hmutex.Unlock();                              //解鎖互次對象
		}
		else
		{
			hmutex.Unlock();
			break;
		}
	}
	return 0; 
}
DWORD WINAPI myfun2(LPVOID lpParameter)
{
	while(1)
	{
		hmutex.Lock(INFINITE);
		if(a < 1000)
		{
			a += 1;
			::Sleep(1000);
			printf("線程2: %d\r\n", a);
			hmutex.Unlock();
		}
		else
		{
			hmutex.Unlock();
			break;
		}
	}
	return 0; 
}


結果:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章