SPlatten
SPlatten

Reputation: 5762

How to Lambda thread body

I have a class that currently uses a class method as the thread body:

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

    private:
        void threadBody(void);

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

There is a lot more to the class than just the simple example above, the current code looks something like this:

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

The class method "threadBody" looks something like this:

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

Now I've been asked to convert the thread body to Lambda, I'm reading up on how to do this and looking for help on how I achieve the same.

How do I pass the instance of the class so that its members can be accessed in the body of the thread?

Would this be correct?

    m_thread = std::make_unique<std::thread>([this](Something* pInstance) {
        while( pInstance->isRunning ) {
        //Do something here until m_run is false
        }
    });

Upvotes: 1

Views: 168

Answers (3)

selbie
selbie

Reputation: 104569

You don't need to explicitly pass "this" as a parameter if you are already capturing it. Not sure why you need it to be unique_ptr.

Simpler:

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

     };

Constructor:

Something::Something() : m_run(true) {
      m_thread = std::thread([this]() {
          while (isRunning()) {
             // Do Something
          }
      });
  }

Upvotes: 2

Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33944

So it sounds like you want to do away with the class. I guess I would suggest something like the following:

    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();   

Here i have made 2 important changes:

  1. The class is gone and your thread body (do something) is a lambda.
  2. Use an atomic<bool> for your finish loop flag to avoid unsafe thread behaviour.

Here is a live example.

Upvotes: 3

molbdnilo
molbdnilo

Reputation: 66459

You don't need the parameter - you're capturing this and since the lambda is defined in the scope of the class you have the normal accessibility inside a member definition:

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

Upvotes: 2

Related Questions