Forked from facontidavide/problematic_miltithreading.cpp
Created
October 20, 2020 14:00
-
-
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?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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