創建線程
在Windows平臺,Windows API提供了對多線程的支持。
CreateThread用於創建一個線程,其函數原型如下:
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //線程安全相關的屬性,常置爲NULL
SIZE_T dwStackSize, //新線程的初始化棧大小,可設置爲0,表示和主線程棧的大小一樣, 如果不夠用會自動增長
LPTHREAD_START_ROUTINE lpStartAddress, //線程函數
LPVOID lpParameter, //傳入線程函數的參數,不許傳遞參數時爲NULL
DWORD dwCreationFlage, //啓動選項,0:線程建立後立即執行入口函數;CREATE_SUSPENDED:線程建立後會掛起等待
LPDWORD lpThreadId //傳出參數,用於獲得線程ID,如果爲NULL,則不返回線程ID
);
其中線程函數的原型如下:
DWORD WINAPI ThreadProc(LPVOID lpParameter); //lpParameter是傳入的參數,是一個空指針
【demo1】簡單多線程實例
#include<iostream>
#include<Windows.h>
using namespace std;
DWORD WINAPI FunProc(LPVOID lpParameter);
int index=0;
void main()
{
HANDLE hThread;
hThread=CreateThread(NULL,0,FunProc,NULL,0,NULL);
CloseHandle(hThread);
while(index++<20)
cout<<"main is running"<<endl;
system("pause");
}
DWORD WINAPI FunProc(LPVOID lpParameter)
{
while(index++<20)
cout<<"thread is running"<<endl;
return 0;
}
運行結果如圖所示:
線程同步
使用互斥量進行線程同步時會用到一下3個函數:
HANDLE WINAPI CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, //線程安全相關屬性,常置爲NULL
BOOL bInitialOwner, //創建Mutex時的當前線程是否擁有Mutex的所有權
LPCTSTR lpName //Mutex的名稱
);
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle; //要獲取的鎖的句柄
DWORD dwMilliseconds //超時間隔,一般爲INFINITE,表示無限等待,知道等待的對象處於非佔用的狀態
);
BOOL WINAPI ReleadeMutex(HANDLE hMutex); //釋放所擁有的互斥量鎖對象,hMutex爲釋放的互斥量的句柄
【demo2】模擬火車售票系統
#include<iostream>
#include<Windows.h>
using namespace std;
#define NAME_LIRE 40
DWORD WINAPI FunProc(LPVOID lpParameter);
int tickets=100;
HANDLE hMutex;
typedef struct __THREAD_DATA
{
int nMaxNum;
char strThreadName[NAME_LIRE];
__THREAD_DATA():nMaxNum(0)
{
memset(strThreadName,0,NAME_LIRE*sizeof(char));
}
}THREAD_DATA;
void main()
{
THREAD_DATA threadData1,threadData2,threadData3;
strcpy(threadData1.strThreadName,"窗口A");
strcpy(threadData2.strThreadName,"窗口B");
strcpy(threadData3.strThreadName,"窗口C");
//創建互斥對象
hMutex=CreateMutex(NULL,TRUE,"tickets");
if(hMutex)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only one instance can run"<<endl;
return;
}
}
//創建線程
HANDLE hThread1=CreateThread(NULL,0,FunProc,&threadData1,0,NULL);
HANDLE hThread2=CreateThread(NULL,0,FunProc,&threadData2,0,NULL);
HANDLE hThread3=CreateThread(NULL,0,FunProc,&threadData3,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
WaitForSingleObject(hMutex,INFINITE);
ReleaseMutex(hMutex);
ReleaseMutex(hMutex);
Sleep(4000);
system("pause");
}
//線程的入口函數
DWORD WINAPI FunProc(LPVOID lpParameter)
{
THREAD_DATA* pThreadData=(THREAD_DATA*)lpParameter;
while(true)
{
WaitForSingleObject(hMutex,INFINITE);
if(tickets>0)
{
Sleep(1);
cout<<pThreadData->strThreadName<<" 售出第 "<<tickets--<<" 張票"<<endl;
}
else
break;
ReleaseMutex(hMutex);
}
return 0;
}
部分結果如下圖所示: