【问题标题】:Passing an entire class as argument to a thread c++ as in c#将整个类作为参数传递给线程 c++,就像在 c# 中一样
【发布时间】:2018-09-05 16:10:12
【问题描述】:

我来自 C#,习惯于创建某个类的实例,然后调用线程在该对象上执行类方法,修改其特定变量。这是一个 c#-ish 示例:

class myclass
{
  public:
    int i = 0;
    void method ()
    {
      i++;
    }
}
// then my main
myclass obj1 = new myclass(); 
myclass obj2 = new myclass(); 
myclass obj3 = new myclass();
thread first = new thread (obj1.method);
thread second = new thread (obj2.method);
thread third = new thread (obj3.method);

在这里我希望我可以访问 obj1.i、obj2.i、obj3.i 并且它们是 = 1。 我似乎无法在 C++ 中复制这种行为,可能是非常愚蠢的事情,我发现的所有解决方案都是使用静态方法,但这首先违背了我的代码的目的。

【问题讨论】:

  • 我建议您尝试在不使用 new 的情况下重新编写此内容。 C++ 不是 C#
  • 或者,如果你真的想让人们出风头;在它之前添加一个删除;因此得到delete new std::thread(thing)(不认真-不要这样做)
  • 这当然是一个例子,因为我不知道如何用 C++ 编写这个,这是问题的重点,如果你不想帮忙,为什么还要麻烦回答? :(
  • 要获取非静态成员函数的地址,C++ 语法为&myclass::method。仅仅靠猜测,你永远不会得到正确的 C++。
  • @MicheleEmiliani 这不是在 C++ 中做this;它是关于缺少一些核心语言功能,例如如何在堆栈和堆上创建对象;如何不发生内存泄漏等。最后;我没有回答;这是评论区;我发表评论是为了为您指明如何改进的正确方向。

标签: c# c++ multithreading class


【解决方案1】:

你的 main 应该看起来更像这样

myclass obj1;
myclass obj2;
myclass obj3;
thread first(&myclass::method, obj1);
thread second(&myclass::method, obj2);
thread third(&myclass::method, obj3);

无需使用new 堆分配任何东西。
要使用成员函数启动线程,您需要传递一个指向该函数的指针和调用该成员函数的对象。

我们还需要确保在之后加入线程。

first.join();
second.join();
third.join();

编辑

std::thread 默认按值接受参数,这意味着在上面的代码中它将复制我们的对象并在副本上运行成员函数。

如果我们想让成员函数在我们传入的实际对象上运行,我们需要像这样使用std::reference_wrapper

thread first(&myclass::method, std::ref(obj1));

有点累,我的疏忽。但现在更新了。

【讨论】:

  • @MicheleEmiliani 我错过了一个重要的细节,请查看编辑。
  • 我已经在 C++ 中使用线程完成了一些工作程序,并且我包括了#include 但是构建给了我这个错误:/tmp/cc6radFB.o: In function std::thread::thread<void (myclass::*)(), std::reference_wrapper<myclass> >(void (myclass::*&&)(), std::reference_wrapper<myclass>&&)': main.cpp:(.text._ZNSt6threadC2IM7myclassFvvEJSt17reference_wrapperIS1_EEEEOT_DpOT0_[_ZNSt6threadC5IM7myclassFvvEJSt17reference_wrapperIS1_EEEEOT_DpOT0_]+0x24): undefined reference to pthread_create' collect2: error : ld 返回 1 退出状态终端进程以退出代码终止:1
  • @MicheleEmiliani 您需要在构建时链接线程。在我的带有 g++ 的 linux 机器上,可以通过在链接/构建最终二进制文件时将 -pthread 添加到编译器选项来完成。在带有 Visual Studio 的 Windows 上,我猜它会使用其他一些标志。
【解决方案2】:

我认为这段代码可以满足您的需求:

#include <string>
#include <iostream>
#include <thread>

using namespace std;

class myclass {
  public:
    myclass(int _i) {
      this->i = _i;
    }
    int i = 0;
    void method () {
      i++;
      cout << "Method " << i << "\n";
    }
};

int main()
{
  myclass obj1(1);
  myclass obj2(2);
  myclass obj3(3);

  thread t1(&myclass::method, obj1);
  thread t2(&myclass::method, obj2);
  thread t3(&myclass::method, obj3);

  //Wait for finish all threads 
  t1.join();
  t2.join();
  t3.join();
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    相关资源
    最近更新 更多