Win32API下的多執行緒程式設計入門
多執行緒,Multi-Thread。移步別處理解Thread和Process。多執行緒可用多種API實現,這裡用Win32 API實現最簡單的多執行緒,執行緒彼此獨立,不涉及執行緒間的資料共享。
先直接上程式:
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <string>
#include <iostream>
class ThreadX
{
private:
std::string threadName;
int loopStart;
int loopEnd;
int loopStep;
public:
ThreadX(int x, int y, int z) : loopStart(x), loopEnd(y), loopStep(z) { }
void SetThreadName(std::string name)
{
threadName = name;
}
static unsigned __stdcall ThreadEntryPoint(void* pThis)
{
ThreadX* pTh = (ThreadX*)pThis;
pTh->StartUp();
return 1;
}
void StartUp()
{
for (int i = loopStart; i < loopEnd; ++i)
{
if (i % loopStep == 0)
{
//std::cout << threadName << ": " << i << std::endl;
printf("%s : %d \n", threadName.c_str(), i);
}
}
printf("%s terminating...\n", threadName.c_str());
}
};
int main()
{
ThreadX* obj1 = new ThreadX(0, 1000000, 20000);
obj1->SetThreadName("Thread1");
HANDLE hThread1;
unsigned thread1Id;
hThread1 = (HANDLE)_beginthreadex(NULL,
0,
ThreadX::ThreadEntryPoint,
obj1,
CREATE_SUSPENDED,
&thread1Id);
if (hThread1 == NULL)
{
printf("Failed to create Thread 1. \n");
}
DWORD dwExitCode;
GetExitCodeThread(hThread1, &dwExitCode);
printf("initial thread 1 exit code = %d \n", dwExitCode);
ThreadX* obj2 = new ThreadX(-1000000, 0, 20000);
obj2->SetThreadName("Thread2");
HANDLE hThread2;
unsigned thread2Id;
hThread2 = (HANDLE)_beginthreadex(NULL,
0,
ThreadX::ThreadEntryPoint,
obj2,
CREATE_SUSPENDED,
&thread2Id);
if (hThread2 == NULL)
{
printf("Failed to create Thread 1. \n");
}
GetExitCodeThread(hThread1, &dwExitCode);
printf("initial thread 2 exit code = %d \n", dwExitCode);
ResumeThread(hThread1);
ResumeThread(hThread2);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
GetExitCodeThread(hThread1, &dwExitCode);
printf("thread 1 exit with code : %d \n", dwExitCode);
GetExitCodeThread(hThread2, &dwExitCode);
printf("thread 2 exit with code : %d \n", dwExitCode);
CloseHandle(hThread1);
CloseHandle(hThread2);
delete(obj1);
obj1 = NULL;
delete(obj2);
obj2 = NULL;
system("pause");
return 0;
}
執行結果如下:
記錄以下幾點。
1.
hThread1 = (HANDLE)_beginthreadex(NULL,
0,
ThreadX::ThreadEntryPoint,
obj1,
CREATE_SUSPENDED,
&thread1Id);
ResumeThread(hThread1);
WaitForSingleObject(hThread1, INFINITE);
GetExitCodeThread(hThread1, &dwExitCode);
CloseHandle(hThread1);
這個Sample裡用到的關於多執行緒的Win32 API就上面的幾個粗體標示的函式。
注意:
(1)用_beginthreadex 而非CreateThread,因為CreateThread用於CRT時會導致記憶體洩露。
官方說明如下:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
“A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and_endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.”
(2) _beginthreadex 建立的程式被Suspend了,所以才需要後面的ResumeThread(hThread1) 將程式喚醒。
(3)當執行緒還存活時,GetExitCodeThread返回的是259,當執行緒執行結束時,返回的是1.
2.
輸出資訊時,推薦用printf,不容易被其他進行插斷。用cout時,stream容易在不同Thread中跳轉。 如果將StartUp()函式裡的資訊輸入用註釋的那行代替printf那行,執行結果容易出現這種問題:
3.
為了顯示出多執行緒的同時執行,即最終的執行結果裡Thread1和Thread2的資訊穿插輸出,需要保證StartUp()裡迴圈的次數夠多才輸出資訊,否則其他Thread來不及插隊列印資訊。
比如,將
ThreadX* obj1 = new ThreadX(0, 1000000, 20000);
ThreadX* obj2 = new ThreadX(-1000000, 0, 20000);
改為
ThreadX* obj1 = new ThreadX(10, 600, 7);
ThreadX* obj2 = new ThreadX(10001, 10900, 9);
執行結果就變為:
即看起來像是一個執行緒執行結束後才開始另一個執行緒。 不是我們想看到的效果-_-
最後,推薦一個多執行緒入門的教程:http://www.codeproject.com/Articles/14746/Multithreading-Tutorial ,講解和例子都很棒,尤其是前面4個例子。
相關文章
- iOS多執行緒程式設計入門iOS執行緒程式設計
- Java多執行緒程式設計入門(轉)Java執行緒程式設計
- Linux系統下的多執行緒程式設計入門(轉)Linux執行緒程式設計
- Linux下的多執行緒程式設計Linux執行緒程式設計
- 入門python多執行緒/多程式Python執行緒
- 多執行緒程式設計執行緒程式設計
- Linux程式多執行緒入門Linux執行緒
- Linux下的多執行緒程式設計(轉)Linux執行緒程式設計
- DELPHI下的多執行緒程式設計(1) (轉)執行緒程式設計
- DELPHI下的多執行緒程式設計(2) (轉)執行緒程式設計
- iOS多執行緒程式設計總結(下)iOS執行緒程式設計
- Java多執行緒(一)多執行緒入門篇Java執行緒
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Boost多執行緒程式設計執行緒程式設計
- UNIX多執行緒程式設計執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- Java多執行緒入門Java執行緒
- 程式設計思想之多執行緒與多程式(3):Java 中的多執行緒程式設計執行緒Java
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- 多執行緒程式設計,處理多執行緒的併發問題(執行緒池)執行緒程式設計
- Python多執行緒程式設計深度探索:從入門到實戰Python執行緒程式設計
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- iOS多執行緒程式設計:執行緒同步總結iOS執行緒程式設計
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- 多執行緒與高併發(一)多執行緒入門執行緒
- Java多執行緒學習(一)Java多執行緒入門Java執行緒
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- 程式設計思想之多執行緒與多程式(4):C++ 中的多執行緒程式設計執行緒C++
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- C#多執行緒程式設計(1):執行緒的啟動C#執行緒程式設計
- python 多執行緒程式設計Python執行緒程式設計
- Python多執行緒程式設計Python執行緒程式設計
- GCD 與多執行緒程式設計GC執行緒程式設計
- IOS多執行緒程式設計:概述iOS執行緒程式設計
- C#多執行緒程式設計C#執行緒程式設計
- linux 多執行緒程式設計Linux執行緒程式設計
- 多執行緒程式設計ExecutorService用法執行緒程式設計