Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ClaymorePT/6c7ff982e2eaf7b2786cf1889041cf13 to your computer and use it in GitHub Desktop.
Save ClaymorePT/6c7ff982e2eaf7b2786cf1889041cf13 to your computer and use it in GitHub Desktop.
This simple multithreading C++ may sometimes crash (SIGSEGV) or remain blocked forever inside waitStart. Can you figure out why?
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
// The purpose of the this apparently fine application is to make you appreciate thread santizers
// https://clang.llvm.org/docs/ThreadSanitizer.html
class Foo{
public:
Foo(): _start_requested(false), _stop_requested(false), _thread( &Foo::loop, this )
{}
void loop()
{
while(!_stop_requested)
{
waitStart();
std::cout << "loop" << std::endl;
std::this_thread::sleep_for( std::chrono::milliseconds(200) );
}
}
void waitStart()
{
std::unique_lock<std::mutex> lock(_mutex);
while( !_start_requested )
{
_start_signaler.wait(lock);
}
}
void startLoop()
{
std::unique_lock<std::mutex> lock(_mutex);
_start_requested = true;
_start_signaler.notify_all();
}
void stopLoop()
{
_stop_requested = true;
_thread.join();
}
private:
std::atomic_bool _start_requested;
std::atomic_bool _stop_requested;
std::thread _thread;
std::mutex _mutex;
std::condition_variable _start_signaler;
};
int main()
{
Foo foo;
foo.startLoop();
std::this_thread::sleep_for( std::chrono::seconds(1) );
foo.stopLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment