轉載自: http://blog.chinaunix.net/uid-26275986-id-3886498.html
進程是系統中的重要概念,簡單來說字面的意思就是一個運行中的程式,但是程式代表的是靜態指令代碼。進程由系統管理的核心對象和存放程式運行資源的地址空間組成。核心對象由系統管理,因此應用程式是無法直接存取的;地址空間中則包含著程式運行所需的所有資源,如可執行模組、DLL、代碼和資料,以及動態分配的棧與堆。可以說,其實進程就是程式啟動並執行資源的容器。但是進程只是為程式的執行提供了一個場所,真正實現執行流程的是線程。每個進程啟動時都會自動建立一個線程作為主線程,由它去建立其他的線程。線程與進程相比更為輕量級,二者的主要聯絡在於:
1. 線程建立在進程的地址空間中,對於進程資源有著完整存取,多線程間共用資源,可自由通訊;
2. 線程建立時也有自己的核心對象和線程棧,而非地址空間;
3. 一般需要實現多任務時我們更推薦使用線程實現,因為建立一個進程需要分配地址空間,而且進程間的切換也很不方便,即使用進程開銷很高;
一、建立多線程
簡單瞭解了進程與線程的概念之後,我們來看看如何在程式中建立線程。Windows SDK為我們提供了建立線程的專用函數:CreateThread()
點擊(此處)摺疊或開啟 HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpsa,
DWORD cbStack,
LPTHREAD_START_ROUTINE lpStartAddr,
LPVOID lpvThreadParam,
DWORD fdwCreate,
LPDWORD lpIDThread
); -1-第一個參數是安全屬性結構,主要控制該線程控制代碼是否可為進程的子進程繼承使用,預設使用NULL時表示不能繼承;若想繼承線程控制代碼,則需要設定該結構體,將結構體的bInheritHandle成員初始化為TRUE;
-2-cbStack表示的線程初始棧的大小,若使用0則表示採用預設大小初始化;
-3-lpStartAddr表示線程開始的位置,即線程要執行的函數代碼,這點有點類似於回呼函數的使用;
-4-lpvThreadParam用來接收線程過程函數的參數,不需要時可以設定為NULL;
-5-fdwCreate表示建立線程時的標誌,CREATE_SUSPENDED表示線程建立後掛起暫不執行,必須調用ResumeThread才可以執行,0表示線程建立之後立即執行
-6-lpIDThread用來儲存線程的ID;
瞭解了CreateThread函數的用法,我們來看一個例子實際體驗一下。下面的例子會開啟一個線程迴圈輸出資訊,我們可以查看結果:
點擊(此處)摺疊或開啟 //MultiThread
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
int main()
{
int j = 0;
HANDLE hThread_1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
CloseHandle(hThread_1);
while (j++ < 1000)
cout << "MainThread is running for" << " the "<< j <<" times "<<endl;
system("pause");
return 0;
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
int i = 0;
while (i++ < 1000)
cout << "Thread 1 is running for" <<" the "<< i <<" times "<<endl;
return 0;
} 由於我們使用system("pause")命令,因此我們不需要Sleep()命令同樣可以看到主線程和分線程的交替執行:
二、多線程的問題
上面的程式我們只是建立一個新線程,如果建立兩個呢。下面我們類比一個火車售票的模型,線程1和線程2同時負責售票,主線程負責平台搭建。線程1和線程2分別訪問全域變數tickets,輸出其值作為票號然後將其值減一,直至“售完”所有票:
點擊(此處)摺疊或開啟 //MultiThread
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int tickets = 100;
int main()
{
HANDLE hThread_1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
HANDLE hThread_2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
CloseHandle(hThread_1);
CloseHandle(hThread_2);
system("pause");
return 0;
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
while (true)
{ if (tickets > 0)
{
Sleep(10);
cout << "Thread 1 sell ticket : "<<tickets--<<endl;
}
else
break; }
return 0;
}
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
while (true)
{
if (tickets > 0)
{
Sleep(10);
cout << "Thread 2 sell ticket : "<<tickets--<<endl;
}
else
break;
}
return 0;
}