在C++中,_beginthreadex 創建線程是很麻煩的。要求入口函數必須是類的靜態函數。
通常,可以采用thunk,或者模板來實現。
因C++ 11中引入了 std::async ,可以很好的解決這個問題了。
值得注意的是,在循環中 std::async 創建線程,我試了好多次總是失敗,后來看老外的代碼,采用 std::move解決了問題。
具體見實現代碼。
// ConsoleApplication1.cpp : 定義控制台應用程序的入口點。 #include "stdafx.h" #include <iostream> #include <windows.h> #include <functional> #include <process.h> #include <thread> #include <iostream> #include <vector> #include <algorithm> #include <functional> #include <iterator> #include <future> #include <list> #include <sstream> using namespace std; typedef UINT(WINAPI* THREADPROC)(LPVOID); class XTest { public: XTest() {}; ~XTest() {}; UINT XTest::RunLoop(LPVOID obj) { int count = 0; for (int i = 0; i < 5; i++) { Sleep(100); std::ostringstream ostr; ostr << "線程" << (INT)obj << " 靜態執行次數 [" << count++ << "] -RunLoop- " << std::endl; cout << ostr.str().c_str() << std::endl; } return 0; } UINT XTest::XFH() { // 問題就出在這里,_beginthreadex不能調用類的成員函數,須靜態的才行。 //int rt = _beginthreadex(NULL, 0, (THREADPROC) [this](LPVOID) { return this->RunLoop(0); }, 0, 0, NULL); // auto pppp = (&XTest::RunLoop); // ULONG_PTR* kkkk = (ULONG_PTR*)&pppp; std::list<std::future<UINT> > lk; for (int i =0 ; i<8 ; i++) { //auto __p = std::async(std::launch::async , [this, i]() {return this->RunLoop((LPVOID)i); }); auto __p = std::async(std::launch::async, &XTest::RunLoop, this, (LPVOID)i); // __p.wait(); 不可以調用。否則會變成同步了。 lk.push_back(std::move(__p)); // 這里必須要用move,否則就會變成同步了。。測試是會報錯。 //auto k = std::thread([this , i]() {this->RunLoop((LPVOID)i); }); //k.detach(); } // 此行代碼用於等線程結束,會阻塞主線程。 for (auto &e : lk) { e.wait(); } cout << "等線程結束" << endl; Sleep(1000); return 0; } }; int main() { auto mmm = new XTest; mmm->XFH(); cout << "------"; getchar(); return 0; }
C++在函數定義的時候在后面加上=delete是什么意思例如:RoundRobin(const RoundRobin& rhs) = delete;
即將該函數定義成已刪除的函數,任何試圖調用它的行為將產生編譯期錯誤。是C++11標准的內容。
lk.push_back(std::move(__p)); ,若果不用move的話會報錯

因為future的拷貝構造函數已經被定義為刪除delete函數。所以需要用move轉移控制權。
