在 C++11 中使用 std::thread 从两个 类 调用函数

Using std::thread to call functions from two Classes in C++11

我正在尝试实施一个 API 应该让用户并行创建两个通信渠道。一个通道使用 TCP,另一个使用 UDP。我有两个 classes 代表两个频道。这些 classes 实现了不同的功能。我想要并行从两个通道到 运行 的功能。为此,我使用 std::thread 创建两个线程,每个线程一个 (class)。 思路如下 头文件看起来像

class Channel_1
{
public:
     int myfunc(int a, int b);
};

class Channel_2
{
public:
    int anotherfunc(int a, int b);
};

在主cpp文件中 包含头文件

int main()
{
  int a = 10, b = 20;
  Channel_1 ch1;
  Channel_2 ch2;

  std::thread t(ch1.myfunc, a,b);
  return 0;
}

我收到错误消息,指出不存在构造函数 std::thread 的实例。

我有以下问题。

  1. 我们不能在线程中调用 class 中的函数吗 构造函数?
  2. 这种使用线程从不同 class 调用函数的想法是否有意义?

你实际上有两个个问题:

  1. 语法错误。您需要传递一个指向成员函数的指针,如

    std::thread t(&Channel_1::myfunc, a, b);
    
  2. 需要在 class 的实例上调用非静态成员函数。此实例必须作为第一个参数传递:

    std::thread t(&Channel_1::myfunc, ch1, a, b);
    

正如一些程序员所说,您需要提供指向函数的指针(静态或非静态)。第三种选择可能是创建一个实现 start() 方法的基础 class,该方法使用此线程构造函数:

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

使用 lambda 的示例。这并不是一个完整的工作示例,它只是为了展示如何使用第三个线程构造函数

class thread_base {
private:
    std::thread m_th;
    bool m_terminated;

    void proxy() {
        // in the new thread
        // add thread_base setup here if needed and
        // call the execute() method in the derived class
        execute();
    }
public:
    thread_base() : m_th(), m_terminated(false) {}
    thread_base(const thread_base&) = delete;
    thread_base& operator=(const thread_base&) = delete;
    thread_base(thread_base&&) = default;
    thread_base& operator=(thread_base&&) = default;
    virtual ~thread_base() { join(); }

    virtual void start() {
        if(joinable()) throw std::runtime_error("thread already running");
        else m_th = std::thread( [this] { proxy(); } );
    }

    inline bool joinable() { return m_th.joinable(); }
    inline void join() { if(joinable()) { m_th.join(); m_terminated=false; } }
    inline void terminate() { m_terminated=true; }
    inline bool terminated() { return m_terminated; }

    virtual void execute() = 0; // implement this in your derived classes
};


class Channel_1 : public thread_base {
    void execute() {
        // runs in a thread
        // with a volontary check if a soft termination
        // request has been issued
        while( !terminated() ) {
            // work
        }
    }
};