如何将Lambda线体

问题描述 投票:0回答:1

我有一个类,目前使用一个类方法作为线程主体。

    class Something {
    public:
        bool isRunning() { return m_run; }

    private:
        void threadBody(void);

        std::unique_ptr<std::thread> m_thread;
        std::atomic<bool> m_run;
    };

除了上面的简单例子之外,这个类还有很多其他的东西,目前的代码是这样的。

  Something::Something() : m_run(true) {
      m_thread = std::make_unique<std::thread>(std::bind(&Something::threadBody, this));
  }

类方法 "threadBody "看起来是这样的。

  void Something::threadBody(void) {
      while( m_run ) {
            //Do something here until m_run is false
      }
  }

现在我被要求将线程体转换为Lambda,我正在阅读如何做到这一点,并寻求帮助,如何实现同样的目标。

我如何传递类的实例,使其成员可以在线程体中被访问?

这样做是否正确?

    m_thread = std::make_unique<std::thread>([this](Something* pInstance) {
        while( pInstance->isRunning ) {
        //Do something here until m_run is false
        }
    });
c++ lambda
1个回答
2
投票

你不需要参数--你是在捕获 this 而且由于lambda是在类的范围内定义的,所以在成员定义内有正常的可访问性。

[this]() {
    while (m_run) {
        // ...
    }
}

2
投票

所以听起来你想取消这个类. 我想我会建议像下面这样。

    std::atomic<bool> finish{false}; 
    std::thread t1 {[&finish]() {          
        unsigned counter = 0;
        while (!finish) {    
            std::cout << "Run " << counter++ << "\n";
            std::this_thread::sleep_for(100ms);
        }
    }};

    std::this_thread::sleep_for(1s);
    finish = true;
    t1.join();   

我在这里做了2个重要的改动:

  1. 类消失了,而你的线程体(do something)是一个lambda.
  2. 使用一个 atomic<bool> 为您 finish loop 标志来避免不安全的线程行为。

下面是一个实际的例子。


2
投票

如果你已经捕捉到了 "this",你就不需要显式地把它作为一个参数。 不知道为什么你需要把它作为 unique_ptr.

简单化。

class Something {
        ...
        std::thread m_thread;

     };

构造者:

Something::Something() : m_run(true) {
      m_thread = std::thread([this]() {
          while (isRunning()) {
             // Do Something
          }
      });
  }
© www.soinside.com 2019 - 2024. All rights reserved.