在类内部使用来自同一类的函数创建线程

28

我希望能够定义一个类,其中包含一些数据成员和一个可以访问这些私有数据成员的函数。

然后,我想要一个公共函数,它创建一些线程,这些线程会操作该类的数据成员。但是我的代码编译起来有些困难。

不用担心互斥量或数据保护,这不会成为问题,因为这只是一些示例代码进行测试。

class foo {
    public:
    void make_foo_func_threads();

    private:
    void foo_func();

    char private_data;
    std::vector<std::thread> some_threads;
}

void foo::foo_func() {
    while(1) {
        private_data = 'A';
    }
}

void foo::make_foo_func_thread() {
    for(...) some_threads.push_back(std::thread(foo_func));
    for(...) some_threads.join();
}
编译器给出了错误提示:

'no matching call to std::thread::thread()'

。显然,第一个参数的转换无法匹配<未解决的重载函数类型>void (foo::*&&)'。嗯,除了编译器很难理解如何解析foo_func之外,我还不知道这意味着什么。我该怎么样才能帮助编译器理解我的意图,让它不再产生任何错误?毫无疑问,我写的代码是不合法的,如果是这种情况,有人可以向我解释一下吗?谢谢!
1个回答

37
foo_func是一个非静态成员函数,它需要一个foo实例来操作。这个实例必须提供给线程构造函数。如果你参考std::thread::thread的参考页面,它会解释在新线程中执行的代码。相关的点是指f是一个成员函数指针:

  • 如果f是类T的成员函数指针,则调用它。返回值被忽略。实际上,执行以下代码:
    • 如果t1的类型是TT的引用或从T派生的类型,则为(t1.*f)(t2, ..., tN)
    • 否则为((*t1).*f)(t2, ..., tN)

所以很明显需要一个实例。

for(...) some_threads.push_back(std::thread(&foo::foo_func, this));

Simple example:

#include <iostream>
#include <thread>
#include <vector>

class foo
{
public:
    void make_foo_func_threads()
    {
        for (int i = 0; i < 5; ++i)
            some_threads.push_back(std::thread(&foo::foo_func, this));
        for (auto& t: some_threads) t.join();
    }

private:
    void foo_func() { std::cout << "Hello\n"; }
    std::vector<std::thread> some_threads;
};

int main()
{
    foo f;
    f.make_foo_func_threads();
}

好的,那很棒!不过有一个问题,我的程序虽然应该有一个无限循环在运行,但是却从 main 函数底部退出了。thread.join() 似乎没有等待线程加入! - FreelanceConsultant
1
@EdwardBird,你可以将完整的程序发布到Stacked-Crooked或类似的网站上,并发布链接吗?或者更好的方法是发布另一个问题以获得其他人的贡献(这个答案和其他答案已回答了所发布的问题)。 - hmjd
3
抱歉,我的错,我没有在主函数中加入"f.make_foo_func_threads();"!很抱歉,现在它能够正常运行,请大家不要惊慌。>.< - FreelanceConsultant
谢谢这个答案,它节省了我的时间。但是我脑海中出现了一个简单的问题,为什么我们在线程中使用类指针或this?我的意思是=some_threads.push_back(std::thread(&foo::foo_func, this)); - Saeed Masoomi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接