有没有办法使用类的成员函数在并发线程中运行而无需在 C++11 中传递 *this?

Posted

技术标签:

【中文标题】有没有办法使用类的成员函数在并发线程中运行而无需在 C++11 中传递 *this?【英文标题】:Is there any way to use a member function of a class to run in a concurrent thread without passing *this in C++11? 【发布时间】:2013-04-01 00:27:19 【问题描述】:

我是 C++11 线程的新手,并尝试使用类的成员函数在并发线程中运行。

在回答我之前的问题时,我收到了以下建议:

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);

我实施了上述建议。它消除了我遇到的编译错误,但引入了运行时错误。在另一个问题中,我收到了删除所有复制机制的建议。其实我不想复制数据,因为代码是有限元分析的,需要很多内存。

有什么办法可以做到吗?

标题类似于以下内容。

SomeClass 
    vector<int*> someVariable;
public:
    ~SomeClass();
    void threadedMethod(bool, bool); // Inside this method the 
                                     // member vector 'someVariable' is used.

    void someMethod();               // In this function the threadedMethod has
                                     // been used twice to make 2 different thread
;

someMethod 实现是,

void SomeClass::someMethod() 
    thread t1(&SomeClass::threadedMethod, *this, arg1, arg2);
    thread t2(&SomeClass::threadedMethod, *this, arg1, arg2);
    t2.join();
    t1.join();

析构函数类似如下,

SomeClass::~SomeClass() 
    int count  = someVariable.size();
    for(int i=0; i < count; i++) 
        delete someVariable[i];
    

threadMethod 访问变量。这些操作是数据并行的。结果,没有线程将写入同一个内存块。同样,读写内存是不同的。在那里,我认为我不需要任何类型的锁。

如您所见,我使用的是*this,这会导致大量复制。我真的需要避免它。任何人都可以建议任何其他方式让我避免复制吗?

如果您需要更多解释,请告诉我。如果在我的能力范围内,我会尽量详细说明。

我正在使用装有 OS X 10.8.3 的 Intel Mac。我在 Xcode 4.6.1 上编码。编译器是 Apple LLVM 4.2(默认编译器)。

【问题讨论】:

您是否尝试过只传递this(而不是*this)? @AndyProwl,你能把它放到答案部分吗?它像魔术一样工作。非常感谢。你拯救了我的一天(嗯,晚上:p)。 我发布了一个答案 :) 它解决了你的问题吗? @AndyProwl。是的。非常感谢朋友。 不客气,很高兴它有帮助! 【参考方案1】:

参数按值传递给std::thread的构造函数。因此,此声明:

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);
//                                         ^^^^^

触发*this 的副本,这不是您想要的。但是,std::thread 也可以接受一个指针,指向要在其上调用成员函数的对象,与std::bind 完全相同。

因此,通过将this(而不是*this)作为参数传递,指针——而不是指向的对象——将按值传递并最终被复制.如您所愿,这将不会触发 SomeClass 的复制构造。

因此,你应该将上面的语句改写如下:

std::thread t1(&SomeClass::threadFunction, this, arg1, arg2);
//                                         ^^^^

【讨论】:

以上是关于有没有办法使用类的成员函数在并发线程中运行而无需在 C++11 中传递 *this?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法使成员函数不能从构造函数调用?

我想在另一个函数中使用一个函数的返回值,而无需再次运行该函数。 (Python)

MFC中多线程中静态函数调用成员函数的问题

JAVA多线程并发问题

成员函数线程安全吗?

java并发安全详解