C++ 11 线程调用类的成员函数解决办法

在C++中,_beginthreadex 创建线程是很麻烦的。要求入口函数必须是类的静态函数。

通常,可以采用thunk,或者模板来实现。

因C++ 11中引入了 std::async ,可以很好的解决这个问题了。

值得注意的是,在循环中 std::async 创建线程,我试了好多次总是失败,后来看老外的代码,采用 std::move解决了问题。

具体见实现代码。

 

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 > 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++ 11 线程调用类的成员函数解决办法)