Windows下C 實現多執行緒

2021-08-06 06:17:56 字數 3943 閱讀 8682

**:

有時候我們想在乙個類中實現多執行緒,主線程在某些時刻獲得資料,可以「通知」子執行緒去處理,然後把結果返回。下面的例項是主線程每隔2s產生10個隨機數,將這10隨機數傳給多執行緒類,讓它接收到資料後馬上列印出來。

首先看類的定義:

[cpp]view plain

copy

print?

#pragma once

#include 

#include // 使用到了atl類

#include 

#include 

using

namespace std;  

class cmultithreadtest  

;  

#pragma once

#include #include // 使用到了atl類

#include #include using namespace std;

class cmultithreadtest

;

類中使用到了alt類,需要包含atlbase.h和altsync.h標頭檔案。函式testthread必須是靜態函式,因為createthread只接受全域性或者靜態函式。

首先先看init()和uninit()函式的實現:

[cpp]view plain

copy

print?

bool cmultithreadtest::init()  

// 掛起的方式建立執行緒

m_hthread = createthread(null, 0, &cmultithreadtest::testthread, this, create_suspended, null);  

if (null == m_hthread)   

// 喚醒執行緒

resumethread(m_hthread);  

return

true;  

}  bool cmultithreadtest::uninit()  

if (m_hthread != null)   

m_notifyevent.close();

return

true;  

}  

bool cmultithreadtest::init()

// 掛起的方式建立執行緒

m_hthread = createthread(null, 0, &cmultithreadtest::testthread, this, create_suspended, null);

if (null == m_hthread)

// 喚醒執行緒

resumethread(m_hthread);

return true;

}bool cmultithreadtest::uninit()

if (m_hthread != null)

return true;

}

atl::cevent的成員函式create接收4個引數,第四個引數指定event的名字(它是可以有名字的),以便在其他程序可以找到該事件,這裡我們不需要使用,把它設定為null,其他引數很容易理解,不贅述。

init()函式值得注意的是我們建立的執行緒是以掛起的方式建立,所以必須呼叫resumethread喚醒執行緒,否則執行緒一值處於沉睡狀態,不執行執行緒函式。

uninit()函式比較簡單,主要通知執行緒執行收尾工作,並釋放類的資源。

下面我們來看看剩下的函式的實現。

[cpp]view plain

copy

print?

dword callback cmultithreadtest::testthread(lpvoid lpparam)  

cmultithreadtest *lpthis = reinterpret_cast

(lpparam);  

return lpthis->testproc();  

}  dword cmultithreadtest::testproc()  

// 列印陣列

for (unsigned int i = 0; i < m_data.size(); i++)  

cout <

// 重置事件

m_notifyevent.reset();  

}  return 0;  

}  void cmultithreadtest::notifydowork(const std::vector &data)    

dword callback cmultithreadtest::testthread(lpvoid lpparam)

cmultithreadtest *lpthis = reinterpret_cast(lpparam);

return lpthis->testproc();

}dword cmultithreadtest::testproc()

// 列印陣列

for (unsigned int i = 0; i < m_data.size(); i++)

首先我們看testthread函式,它是執行緒的「入口「,執行緒被喚醒後執行該函式。值得注意的是,我們在建立執行緒的時候把物件指標this作為引數傳遞給建立執行緒函式,系統在呼叫testthread的時候會把this傳遞回來,這裡使用弱型別轉換reinterpret_cast將lpvoid轉化為cmultithreadtest類的指標,reinterpret_cast是乙個危險的型別轉換,一般只適用於指標和整數之間的轉換。有興趣的同學可以參考c++ primer第4版18.2.1章節。

執行緒函式將引數lpparam轉化為物件指標後,執行物件的成員函式testproc(),testproc()實現主要的邏輯。這裡可能會有人疑問,為什麼不直接在testthread()函式實現主要邏輯呢?這樣做有兩個好處,一是能夠將執行緒函式邏輯和業務邏輯分離,其二就是testthread是個靜態函式,類靜態函式只能處理類的靜態成員變數,而很多時候我們希望執行緒處理類的非靜態成員變數。

最後notifydowork函式很簡單,該函式給外部呼叫,它把外部傳進來的data賦值給類的非靜態成員變數m_data,並通知執行緒處理m_data資料,testproc中waitforsingleobject函式接收到事件後往下執行,把m_data列印出來。

下面我們看看main函式的實現:

[cpp]view plain

copy

print?

int _tmain(int argc, _tchar* argv)  

srand(unsigned int(time(null)));  

std::vector data;  

while (true)  

multithreadtest.uninit();  

return 0;  

}  

int _tmain(int argc, _tchar* argv)

srand(unsigned int(time(null)));

std::vectordata;

while (true)

multithreadtest.uninit();

return 0;

}

這段**就不用解釋了,記得包含標頭檔案windows.h、time.h和vector。

總結:多執行緒類的使用場景是,當乙個執行緒或得到資料後,希望其他執行緒能夠處理這部分數。多執行緒類實現還是比較簡單的,首先建立執行緒和執行緒事件,實現給外部呼叫的介面,外部通過介面設定事件,通知執行緒執行。

windows下C多執行緒

看到乙個簡單的windows程式設計例項,給大家分享一下 這個例項主要用createthread為乙個宣告的方法建立乙個程序,這個被建立的方法必須用dword winapi 修飾,需要有lpvoid 型別的引數,如果沒有這個引數,在建立程序時要對這個方法強制型別中轉換 dword winapi my...

Windows下C 多執行緒同步

程式 是計算機指令的集合,它以檔案的形式儲存在磁碟上。而程序通常被定義為乙個正在執行程式的例項,是乙個程式在其自身位址空間的依次執行活動。程序 執行緒 由執行緒的核心物件和執行緒棧組成 當多執行緒訪問全域性變數時需要多執行緒同步 互斥物件 事件物件 關鍵 段 互斥物件 互斥獨享可以看做是一把房間鑰匙...

Windows下多執行緒常用函式

分類 c ui多執行緒 2011 11 03 16 13 594人閱讀收藏 舉報windows attributes winapi null security 多執行緒 1.執行緒建立 該函式在其呼叫程序的程序空間裡建立乙個新的執行緒,並返回已建執行緒的控制代碼。handle createthrea...