菜鸟笔记
提升您的技术认知

c 11 线程调用类的成员函数解决办法-ag真人游戏

在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标准的内容。


lk.push_back(std::move(__p)); ,若果不用move的话会报错

 

 因为future的拷贝构造函数已经被定义为删除delete函数。所以需要用move转移控制权。

网站地图