開篇
1、WinCE提供了Mutex,Event 和 Semaphore 三種內核機制來實現線程之間的同步。
WinCE提供了兩種用戶態下的同步方法:Critical Section 和互鎖函數(Interlocked Functions)-----------不能跨進程,運行效率高
2、同步對象有兩種狀態:
- 通知(Signaled)
- 未通知(Non-signaled) -------表示同步對象被佔用
Mutex--互斥(內核態)
#include <windows.h>
#include <iostream.h>
//聲明線程入口函數原型
DWORD WINAPI Fun1Proc( LPVOID lpParameter );
DWORD WINAPI Fun2Proc( LPVOID lpParameter );
int tickets = 100; //要銷售的票數還剩下100張
//這100張票由Fun1Proc與Fun2Proc兩個線程負責銷售
HANDLE hMutex;//互斥對象句柄
void main()
{
HANDLE hThread1,hThread2;
hThread1 = CreateThread(
NULL, //使用缺省的安全性
0, //指定初始提交棧的大小
Fun1Proc,//指定線程入口函數地址
NULL, //傳遞給線程的參數
0, //附加標記,0表示線程創建後立即運行
NULL); //線程ID,在Win98/95中不能設置爲NULL
CloseHandle(hThread1);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread2);
// cout<<"main thread is running"<<endl;
// hMutex = CreateMutex(NULL, FALSE,NULL);
//創建一個匿名的互斥對象
hMutex = CreateMutex(NULL, TRUE,"MuName");
//創建一個命名的互斥對象
if(hMutex)
{//判斷是不是第一次創建的互斥對象
if(ERROR_ALREADY_EXISTS == GetLastError())
{//如果爲真,說明互斥對象已經創建
cout<<"已經有一個實例在運行了,只能有一個實例運行同時運行。"<<endl;
return;
}
}
WaitForSingleObject(hMutex,INFINITE);
//因爲請求的互斥對象線程ID與擁有互斥對象線程ID相同,
//可以再次請求成功,計數器加1
ReleaseMutex(hMutex); //第一次釋放,計數器減1,但仍有信號
ReleaseMutex(hMutex); //再一次釋放,計數器爲零
while(tickets>0) { Sleep(4000);}
}//endof main()
/*------------實現線程入口函數Fun1Proc---------------*/
DWORD WINAPI Fun1Proc( LPVOID lpParameter )
{
while(TRUE)
{
WaitForSingleObject(hMutex,INFINITE);
//請求互斥對象
if(tickets>0)
{Sleep(1);
cout<<"thread 1 sell ticket: ";
cout<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
} ///endof Fun1Proc()
/*-----------實現線程入口函數Fun2Proc--------------*/
DWORD WINAPI Fun2Proc( LPVOID lpParameter )
{
while(TRUE)
{
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
{Sleep(1);
cout<<"thread 2 sell ticket: ";
cout<<tickets--<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
} ///endof Fun1Proc()
Semaphore----信標或信號燈,→→帶有引用計數的Mutex (內核態)
Event-----事件(內核態)
#include <windows.h>
#include <iostream.h>
int ticket=100;
HANDLE g_hEvent;//保存事件對象句柄
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
void main()
{
HANDLE thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
HANDLE thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(thread1);
CloseHandle(thread2);
//創建事件對象,可用命名事件對象來控制只運行一個實例
g_hEvent=CreateEvent(NULL,
FALSE, //TRUE人工重置,FALSE 自動重置
FALSE, //初始化狀態,TURE信號狀態,FALSE非信號狀態
"tickets"); //事件對象命名,NULL表示匿名
if(g_hEvent)
{
if(ERROR_ALREADY_EXISTS == GetLastError())
{
cout<<"Only one instance can run!"<<endl;
return;
}
}
SetEvent(g_hEvent);//將事件設置爲有信號狀態
Sleep(4000);
CloseHandle(g_hEvent);
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
WaitForSingleObject(g_hEvent,INFINITE);
while(ticket)
{
cout<<"thread1 sells : "<<ticket--<<endl;
Sleep(1);
SetEvent(g_hEvent);
}
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
WaitForSingleObject(g_hEvent,INFINITE);
while(ticket)
{
cout<<"thread2 sells : "<<ticket--<<endl;
Sleep(1);
SetEvent(g_hEvent);
}
return 0;
}