【问题标题】:Using std::thread to call functions from two Classes in C++11使用 std::thread 从 C++11 中的两个类调用函数
【发布时间】:2019-04-16 09:31:15
【问题描述】:

我正在尝试实现一个 API,让用户可以并行创建两个通信通道。一个通道使用 TCP,另一个使用 UDP。我有两个类代表两个通道。这些类实现了不同的功能。我希望两个通道的功能并行运行。为此,我使用std::thread 创建两个线程,一个用于每个通道(类)。 思路如下 头文件看起来像

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. 我们不能从线程中的类调用函数吗 构造函数?
  2. 这种使用线程调用不同类的函数的想法有意义吗?

【问题讨论】:

    标签: c++ multithreading sockets c++11 stdthread


    【解决方案1】:

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

    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
            }
        }
    };
    

    【讨论】:

    • 基类中的虚拟最终成员?
    • 是的,它应该是公开的并且不能被覆盖。这是我首先想到的,但也许有更好的方法。
    • virtual final 成员的否决票还是其他?
    • 对于基础中的虚拟 final 方法,由于在非连接线程上调用临时 std::thread 的析构函数,用于立即核心转储,以实现不必要的复杂性。
    • 好吧,它不是一个完整的工作基类,而是展示如何使用第三个线程构造函数的东西。我添加了更多样板(尽管仍然不是完整的基类)。至于virtual final 方法,我不知道还有什么方法可以防止它被覆盖。
    【解决方案2】:

    你实际上有两个问题:

    1. 语法错误。您需要将指针传递给成员函数,如

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多