Search code examples
c++multithreadinglambdaatomic

C++ lambda thread stoppable from outside


I'm trying to create a helper thread that waiting and works/finishes if the main thead says so.

Something like this:

std::atomic<bool> quit(false), doit(false);

std::thread([quit, doit]()
{
  while (!quit)
  {
    wait();
    if (doit)
      std::cout << "done";
  }
}

the compiler says:

1.cpp:26:15: error: call to implicitly-del
eted copy constructor of 'atomic<bool>'
    thread t([quit, doit, ,                   ^~~~~~                      /data/data/com.termux/files/usr/include/c+
+/v1/atomic:1643:7: note: copy constructor of 'atomic<bool>' is implicitly deleted b
ecause base class '__atomic_base<bool>' has a deleted copy constructor                  : public __atomic_base<_Tp>

What is the purpose of implicit deletion and why does it matter here? Also: what else should I use (and not mutex)?


Solution

  • std::thread([quit, doit]()
    

    Setting aside the compilation error, for the moment: what this says is that this lambda captures this doit variable by value. So, even if the compilation error magically goes away, the end result will be something that's completely useless and will never work. All the lambda will be doing is checking, over and over again, its captured doit object, a completely different and independent object from the "real" doit object (because that's how lambda captures by value work, after all), that nobody else will ever set, until time comes to an end.

    If doit is a global object it does not need to be captured. If it is not, if it has local scope, the lambda should capture it by reference (using the &-thingy in front of it). And then you will have to make sure, in some form or fashion, that the local scope does not terminate until this execution thread stops, or at least (in some way) it will no longer logically access the captured-by-reference object, so it can be destroyed in its original scope.