vc中,線程同步方法

  首選使用臨界區對象,主要緣由是使用簡單。

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets=100;
CRITICAL_SECTION g_csA;
CRITICAL_SECTION g_csB;

void main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
InitializeCriticalSection(&g_csA);
InitializeCriticalSection(&g_csB);
Sleep(40000);
DeleteCriticalSection(&g_csA);
DeleteCriticalSection(&g_csB);
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while (TRUE)
{
Sleep(100);
EnterCriticalSection(&g_csA);
//EnterCriticalSection(&g_csB); //臨界區的同步和互鎖
if(tickets>0)
{
Sleep(1);
cout<<"Thread1 sell ticket :"<<tickets--<<endl;
//LeaveCriticalSection(&g_csB);
LeaveCriticalSection(&g_csA);
}
else
{
//LeaveCriticalSection(&g_csB);
LeaveCriticalSection(&g_csA);
break;
}
}
return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while (TRUE)
{
Sleep(1);
EnterCriticalSection(&g_csB);
//EnterCriticalSection(&g_csA);
if(tickets>0)
{
Sleep(1);
cout<<"Thread2 sell ticket :"<<tickets--<<endl;
//LeaveCriticalSection(&g_csA);
LeaveCriticalSection(&g_csB);
}
else
{
//LeaveCriticalSection(&g_csA);
LeaveCriticalSection(&g_csB);
break;
}
}
return 0;
ios


2、使用事件對象windows

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int tickets=100;
HANDLE g_hEvent;

void main()
{
HANDLE hThread1;
HANDLE hThread2;
//**************************************************
// 建立一個命名的自動重置事件內核對象
g_hEvent=CreateEvent(NULL,FALSE,FALSE,LPCWSTR("tickets"));
if(g_hEvent)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only _disibled event"<<endl;
}
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
SetEvent(g_hEvent);
Sleep(40000);
//關閉事件對象句柄
CloseHandle(g_hEvent);
}
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while (TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
//ResetEvent(g_hEvent);
if(tickets>0)
{
Sleep(1);
cout<<"thread1 sell ticket :"<<tickets--<<endl;
SetEvent(g_hEvent);
}
else
{
SetEvent(g_hEvent);
break;
}
}
return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while (TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
//ResetEvent(g_hEvent);
if (tickets>0)
{
cout<<"Thread2 sell ticket :"<<tickets--<<endl;
SetEvent(g_hEvent);
}
else
{
SetEvent(g_hEvent);
break;
}
}
return 0;
ide


3、使用互斥對象函數

#include <windows.h>
#include <iostream>
using namespace std; 
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);spa

int index =0;
int tickets=100;
HANDLE hMutex;
void main()
{
HANDLE hThread1;
HANDLE hThread2;
//建立線程
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
//**************************************************************
// 保證應用程序只有一個實例運行,建立一個命名的互斥對象.
hMutex=CreateMutex(NULL,TRUE,LPCWSTR("tickets"));
// 建立時主線程擁有該互斥對象,互斥對象的線程ID爲主線程的ID,同時將該互斥對象內部計數器置爲1
if (hMutex)
{
if (ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only one instance can run!"<<endl;
//Sleep(40000);
return;
}
}
//**************************************************************
WaitForSingleObject(hMutex,INFINITE);
// 使用該函數請求互斥對象時,雖然說該對象處於無信號狀態,但由於請求的線程ID和該互斥對象全部者的線程ID是相同的.
//因此仍然能夠請求到這 個互斥對象,因而該互斥對象內部計數器加1,內部計數器的值爲2.
ReleaseMutex(hMutex);//釋放一次互斥對象,該互斥對 象內部計數器的值遞減1,操做系統不會將這個互斥對象變爲已通知狀態.
ReleaseMutex(hMutex);//釋放一次互斥對象,該互 斥對象內部計數器的值爲0,同時將該對象設置爲已通知狀態.
//對於互斥對象來講,誰擁有誰釋放
Sleep(40000);
}操作系統

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while (TRUE)
{
WaitForSingleObject(hMutex,INFINITE);// 等待互斥對象有信號
if (tickets>0)
{
Sleep(1);
cout<<"thread1 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);// 設置該互斥對象的線程ID爲0,而且將該對象設置爲有信號狀態
}
return 0;
}線程

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while (TRUE)
{
WaitForSingleObject(hMutex,INFINITE);
if (tickets>0)
{
Sleep(1);
cout<<"thread2 sell ticket :"<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
}對象

相關文章
相關標籤/搜索