What's the proper way of implementing 'sleeping' technique using C++? - c++

Two thread. Main one is constantly gathering notifications while the other one is processing some of them.
The way i implemet it - is not correct as i've been told. What problems is it causing and what's wrong about it?
#include <iostream>
#include <atomic>
#include <thread>
#include <mutex>
#include <chrono>
std::condition_variable foo;
std::mutex mtx;
void secondThread()
{
while (true)
{
foo.wait(std::unique_lock<std::mutex>(mtx));
std::cout << " ----------------------------" << std::endl;
std::cout << "|processing a notification...|" << std::endl;
std::cout << " ----------------------------" << std::endl;
}
}
int main()
{
std::thread subThread = std::thread(&secondThread);
int count = 0;
while (true)
{
if (count % 10 == 0)
{
foo.notify_one();
}
std::cout << "Main thread working on gathering notifications..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(300));
count++;
}
return 0;
}
I was told that this foo.wait(std::unique_lock<std::mutex>(mtx)) line of code is not a good practice according to the C++ spec. This is not a proper way of solving this kind of problem. It's also called, sleeping(not busy waiting).

Before you call wait, you must check that the thing you are waiting for hasn't already happened. And before you stop calling wait, you must check that the thing you are waiting for has happened. Condition variables are stateless and have no idea what you're waiting for. It's your job to code that.
Also, the associated mutex must protect the thing you're waiting for. The entire point of a condition variable is to provide an atomic "unlock and wait" operation to prevent this problem:
You check if you need to wait under the protection of a mutex.
You decide you do need to wait.
You unlock the mutex so other threads can make progress.
You wait.
But what if the thing you're waiting for happens after you unlocked the mutex but before you waited? You'll be waiting for something that already happened.
This is why the wait function takes a lock holder -- so that it can perform steps 3 and 4 atomically.

Related

Unexpected behavior when std::thread.detach is called

I've been trying to develop a better understanding of C++ threading, by which I have written the following example:
#include <functional>
#include <iostream>
#include <thread>
class Test {
public:
Test() { x = 5; }
void act() {
std::cout << "1" << std::endl;
std::thread worker(&Test::changex, this);
worker.detach();
std::cout << "2" << std::endl;
}
private:
void changex() {
std::cout << "3" << std::endl;
x = 10;
std::cout << "4" << std::endl;
}
int x;
};
int main() {
Test t;
t.act();
return 0;
}
To me, I should get the following output when compiled with g++ linked with -pthread:
1
2
3
4
as the cout calls are in that order. However, the output is inconsistent. 1 and 2 are always printed in order, but sometimes the 3 and or 4 are either omitted or printed double. i.e. 12, 123, 1234, or 12344
My working theory is that the main thread exits before the worker thread begins working or completes, thus resulting in the omission of output. I can immediately think of a solution to this problem in creating a global boolean variable to signify when the worker thread has completed that the main thread waits on for a state change before exiting. This alleviates the issue.
However, this feels to me like a highly messy approach that likely has a more clean solution, especially for an issue like this that likely comes up often in threading.
Just some general advice, that holds both for using raw pthreads in C++ and for pthreads wrapped in std::thread: The best way to get readable, comprehensible and debuggable behavior is to make thread synchronization and lifetime management explicit. I.e. avoid using pthread_kill, pthread_cancel, and in most cases, avoid detaching threads and instead do explicit join.
One design pattern I like is using an std atomic flag. When main thread wants to quit, it sets the atomic flag to true. The worker threads typically do their work in a loop, and check the atomic flag reasonably often, e.g. once per lap of the loop. When they find main has ordered them to quit, they clean up and return. The main thread then join:s with all workers.
There are some special cases that require extra care, for example when one worker is stuck in a blocking syscall and/or C library function. Usually, the platform provides ways of getting out of such blocking calls without resorting to e.g. pthread_cancel, since thread cancellation works very badly with C++. One example of how to avoid blocking is the Linux manpage for getaddrinfo_a, i.e. asynchronous network address translation.
One additional nice design pattern is when workers are sleeping in e.g. select(). You can then add an extra control pipe between main and the worker. Main signals the worker to quit by send():ing one byte over the pipe, thus waking up the worker if it sleeps in select().
Example of how this could be done:
#include <functional>
#include <iostream>
#include <thread>
class Test {
std::thread worker; // worker is now a member
public:
Test() { x = 5; } // worker deliberately left without a function to run.
~Test()
{
if (worker.joinable()) // worker can be joined (act was called successfully)
{
worker.join(); // wait for worker thread to exit.
// Note destructor cannot complete if thread cannot be exited.
// Some extra brains needed here for production code.
}
}
void act() {
std::cout << "1" << std::endl;
worker = std::thread(&Test::changex, this); // give worker some work
std::cout << "2" << std::endl;
}
// rest unchanged.
private:
void changex() {
std::cout << "3" << std::endl;
x = 10;
std::cout << "4" << std::endl;
}
int x;
};
int main() {
Test t;
t.act();
return 0;
} // test destroyed here. Destruction halts and waits for thread.

c++ std::thread: Is this code guaranteed to deadlock?

The following code is from modernescpp. I understand that when the lock_guard in the main thread holding the mutex causes the deadlock. But since the created thread should start to run once it is initialized. Is there a chance that after line 15 the functions lock_guard on line 11 already grabbed coutMutex so the code runs without any problem? If it is possible, under what circumstance the created thread
will run first?
#include <iostream>
#include <mutex>
#include <thread>
std::mutex coutMutex;
int main(){
std::thread t([]{
std::cout << "Still waiting ..." << std::endl;
std::lock_guard<std::mutex> lockGuard(coutMutex); // Line 11
std::cout << std::this_thread::get_id() << std::endl;
}
);
// Line 15
{
std::lock_guard<std::mutex> lockGuard(coutMutex);
std::cout << std::this_thread::get_id() << std::endl;
t.join();
}
}
Just so the answer will be posted as an answer, not a comment:
No, this code is not guaranteed to deadlock.
Yes, this code is quite likely to deadlock.
In particular, it's possible for the main thread to create the subordinate thread, and then both get suspended. From that point, it's up to the OS scheduler to decide which to run next. Since the main thread was run more recently, there's a decent chance it will select the subordinate thread to run next (assuming it attempts to follow something vaguely like round-robin scheduling in the absence of a difference in priority, or something similar giving it a preference for which thread to schedule).
There are various ways to fix the possibility of deadlock. One obvious possibility would be to move the join to just outside the scope in which the main thread holds the mutex:
#include <iostream>
#include <mutex>
#include <thread>
std::mutex coutMutex;
int main(){
std::thread t([]{
std::cout << "Still waiting ..." << std::endl;
std::lock_guard<std::mutex> lockGuard(coutMutex); // Line 11
std::cout << std::this_thread::get_id() << std::endl;
}
);
// Line 15
{
std::lock_guard<std::mutex> lockGuard(coutMutex);
std::cout << std::this_thread::get_id() << std::endl;
}
t.join();
}
I'd also avoid locking a mutex for the duration of using std::cout. cout is typically slow enough that doing so will make contention over the lock quite likely. It's typically doing to be better to (for only one example) format the data into a buffer, put the buffer into a queue, and have a single thread that reads items from the queue and shoves them out to cout. This way you only have to lock for long enough to add/remove a buffer to/from the queue.

C++ condition_variable wait_for returns instantly

This is simple code from http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
Why does wait_for() return instantly if I comment line with starting thread?
Like this:
// condition_variable::wait_for example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
std::condition_variable cv;
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main ()
{
std::cout << "Please, enter an integer (I'll be printing dots): ";
//std::thread th (read_value);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout) {
std::cout << '.';
}
std::cout << "You entered: " << value << '\n';
//th.join();
return 0;
}
Update:
Please don't look for other problems in this example (related buffering cout ...). The original question was about why wait_for is skipped.
Short answer: compile with -pthread and your issue will go away.
Update:
This is a confirmed bug/issue in libstdc++. Without -pthread being passed in as a compiler flag, the timed wait call will return immediately. Given the history of the issue (3 years), it's not likely to be fixed anytime soon. Anyway, read my message below on why you should be using condition variables with predicates to avoid the spurious wakeup problem. It still holds true even if you are linking with the posix threads library.
That sample code on cplusplus.com has several issues. For starters, amend this line:
std::cout << '.';
To be like this:
std::cout << '.';
std::cout.flush()
Otherwise, you won't see any dots if stdout isn't getting flushed.
If you compile your program (with the thread commented out) like this:
g++ yourcode.cpp -std=c++11
Then the resulting a.out program exhibits the issue you described when the thread is not used. That is, there's a spurious wakeup when the thread is not used. It's like there's a phantom notify() call being invoked on the condition variable from some unknown source. This is odd, but not impossible.
But as soon as you uncomment out the declaration of the thread variable, the program will throw an exception (and crash) as a result of the program not using a multithreaded:
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
Please, enter an integer (I'll be printing dots): Aborted (core dumped)
Interesting, so let's fix that by recompiling with -pthread
g++ yourcode.cpp -std=c++11 -pthread
Now everything works as expected with or without the thread. No more spurious wakeup it seems.
Now let's talk about why you are seeing the behavior you are seeing. Programs using condition variables should always be written to deal with spurious wakeup. And preferably, use a predicate statement. That is, you might get a phantom notify causing your wait or wait_for statement to return early. The example code on the web from cplusplus.com doesn't use a predicate nor does it deal with this possibility.
Let's amend it as follows:
Change this block of code:
while (cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout) {
std::cout << '.';
}
To be this:
while (cv.wait_for(lck,std::chrono::seconds(1), condition_check)==false) {
std::cout << '.';
std::cout.flush();
}
And then elsewhere outside of main, but after the declaration of value, add this function:
bool condition_check() {
return (value != 0);
}
Now the wait loop will wake up every second and/or when the notify call is made by the input thread. The wait loop will continue until value != 0. (Technically, value should be synchronized between threads, either with the lock or as a std::atomic value, but that's a minor detail).
Now the mystery is why does the non-predicate version of wait_for suffer from the spurious wake_up problem. My guess is that's an issue with the single threaded C++ runtime that goes away when the multithreaded runtime (-pthread) is used. Perhaps condition_variable has different behavior or a different implementation when the posix thread library is linked in.
There are several issue with this code:
First, as you have noticed, the program has to be build with the -pthread option.
Second, you need to flush the output if you want to see the dots printed.
Most importantly, this is entirely incorrect usage of mutex and condition variable. A condition variable notification indicates a change of value in a user-specified predicate/condition: the changing of the condition and examining it must be atomic and serialized: otherwise there is a data race and the behavior of the program would be undefined.
As is the case with the example program: value is read and written by two threads, but without any concurrency control mechanism, or to put it differently, there's no "happens-before" relation between the operation, which reads value and the operation which writes value.
Fixed example follows:
// condition_variable::wait_for example
#include <chrono> // std::chrono::seconds
#include <condition_variable> // std::condition_variable, std::cv_status
#include <iostream> // std::cout
#include <mutex> // std::mutex, std::unique_lock
#include <thread> // std::thread
std::mutex mtx;
std::condition_variable cv;
int value;
void read_value() {
int v;
std::cin >> v;
std::unique_lock<std::mutex> lck(mtx);
value = v;
cv.notify_one();
}
int main() {
std::cout << "Please, enter an integer (I'll be printing dots): ";
std::thread th(read_value);
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
std::cout << '.' << std::flush;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
So, what are the changes:
mutex is moved to global scope (for the sake of the example), so the thread, which reads value can lock it, in order to modify value.
the read is in a separate variable; it cannot be directly into value, because value must be modified only under the protection of the mutex, but holding the mutex, while waiting from input form std::cin would prevent the main thread from printing dots, as it will try to acquire the mutex upon timeout.
after each dot output, the std::cout is flushed

Implementing a Semaphore with std::mutex

As a learning exercise, I'm just trying to make a Semaphore class using std::mutex and a few other things provided by the C++ standard. My semaphore should allow as many readLock() as needed, however a writeLock() can only be acquired after all reads are unlocked.
//Semaphore.h
#include <mutex>
#include <condition_variable>
class Semaphore{
public:
Semaphore();
void readLock(); //increments the internal counter
void readUnlock(); //decrements the internal counter
void writeLock(); //obtains sole ownership. must wait for count==0 first
void writeUnlock(); //releases sole ownership.
int count; //public for debugging
private:
std::mutex latch;
std::unique_lock<std::mutex> lk;
std::condition_variable cv;
};
//Semaphore.cpp
#include "Semaphore.h"
#include <condition_variable>
#include <iostream>
using namespace std;
Semaphore::Semaphore() : lk(latch,std::defer_lock) { count=0; }
void Semaphore::readLock(){
latch.lock();
++count;
latch.unlock();
cv.notify_all(); //not sure if this needs to be here?
}
void Semaphore::readUnlock(){
latch.lock();
--count;
latch.unlock();
cv.notify_all(); //not sure if this needs to be here?
}
void Semaphore::writeLock(){
cv.wait(lk,[this](){ return count==0; }); //why can't std::mutex be used here?
}
void Semaphore::writeUnlock(){
lk.unlock();
cv.notify_all();
}
My test program will writeLock() the semaphore, start a bunch of threads, and then release the semaphore. Immediately afterwards, the main thread will attempt to writeLock() the semaphore again. The idea is that when the semaphore becomes unlocked, the threads will readLock() it and prevent the main thread from doing anything until they all finish. When they all finish and release the semaphore, then the main thread can acquire access again. I realize this may not necessarily happen, but it's one of the cases I'm looking for.
//Main.cpp
#include <iostream>
#include <thread>
#include "Semaphore.h"
using namespace std;
Semaphore s;
void foo(int n){
cout << "Thread Start" << endl;
s.readLock();
this_thread::sleep_for(chrono::seconds(n));
cout << "Thread End" << endl;
s.readUnlock();
}
int main(){
std::srand(458279);
cout << "App Launch" << endl;
thread a(foo,rand()%10),b(foo,rand()%10),c(foo,rand()%10),d(foo,rand()%10);
s.writeLock();
cout << "Main has it" << endl;
a.detach();
b.detach();
c.detach();
d.detach();
this_thread::sleep_for(chrono::seconds(2));
cout << "Main released it" << endl;
s.writeUnlock();
s.writeLock();
cout << "Main has it " << s.count << endl;
this_thread::sleep_for(chrono::seconds(2));
cout << "Main released it" << endl;
s.writeUnlock();
cout << "App End" << endl;
system("pause"); //windows, sorry
return 0;
}
The program throws an exception saying "unlock of unowned mutex". I think the error is in writeLock() or writeUnlock(), but I'm not sure. Can anyone point me in the right direction?
EDIT: There was a std::defer_lock missing when initializing lk in the constructor, however it didn't fix the error I was getting. As mentioned in the comment, this isn't a semaphore and I apologize for the confusion. To reiterate the problem, here is the output that I get (things in parenthesis are just my comments and not actually in the output):
App Launch
Thread Start
Thread Start
Main has it
Thread Start
Thread Start
Thread End (what?)
Main released it
f:\dd\vctools\crt_bld\self_x86\crt\src\thr\mutex.c(131): unlock of unowned mutex
Thread End
Thread End
Thread End
This is definitely not a "semaphore".
Your Semaphore constructor acquires the lock on latch right away, then you unlock it twice because writeUnlock() calls lk.unlock() and the next call to writeLock() tries to wait on a condition variable with an unlocked mutex, which is undefined behaviour, then you the next call to writeUnlock() tries to unlock an unlocked mutex, which is also undefined behaviour.
Are you sure the constructor should lock the mutex right away? I think you want to use std::defer_lock in the constructor, and then lock the mutex in writeLock().

Using boost::lock_guard for simple shared data locking

I am a newcomer to the Boost library, and am trying to implement a simple producer and consumer threads that operate on a shared queue. My example implementation looks like this:
#include <iostream>
#include <deque>
#include <boost/thread.hpp>
boost::mutex mutex;
std::deque<std::string> queue;
void producer()
{
while (true) {
boost::lock_guard<boost::mutex> lock(mutex);
std::cout << "producer() pushing string onto queue" << std::endl;
queue.push_back(std::string("test"));
}
}
void consumer()
{
while (true) {
boost::lock_guard<boost::mutex> lock(mutex);
if (!queue.empty()) {
std::cout << "consumer() popped string " << queue.front() << " from queue" << std::endl;
queue.pop_front();
}
}
}
int main()
{
boost::thread producer_thread(producer);
boost::thread consumer_thread(consumer);
sleep(5);
producer_thread.detach();
consumer_thread.detach();
return 0;
}
This code runs as I expect, but when main exits, I get
/usr/include/boost/thread/pthread/mutex.hpp:45:
boost::mutex::~mutex(): Assertion `!pthread_mutex_destroy(&m)' failed.
consumer() popped string test from queue
Aborted
(I'm not sure if the output from consumer is relevant in that position, but I've left it in.)
Am I doing something wrong in my usage of Boost?
A bit off-topic but relevant imo (...waits for flames in comments).
The consumer model here is very greedy, looping and checking for data on the queue continually. It will be more efficient (waste less CPU cycles) if you have your consumer threads awakened determistically when data is available, using inter-thread signalling rather than this lock-and-peek loop. Think about it this way: while the queue is empty, this is essentially a tight loop only broken by the need to acquire the lock. Not ideal?
void consumer()
{
while (true) {
boost::lock_guard<boost::mutex> lock(mutex);
if (!queue.empty()) {
std::cout << "consumer() popped string " << queue.front() << " from queue" << std::endl;
queue.pop_front();
}
}
}
I understand that you are learning but I would not advise use of this in 'real' code. For learning the library though, it's fine. To your credit, this is a more complex example than necessary to understand how to use the lock_guard, so you are aiming high!
Eventually you will most likely build (or better if available, reuse) code for a queue that signals workers when they are required to do work, and you will then use the lock_guard inside your worker threads to mediate accesses to shared data.
You give your threads (producer & consumer) the mutex object and then detach them. They are supposed to run forever. Then you exit from your program and the mutex object is no longer valid. Nevertheless your threads still try to use it, they don't know that it is no longer valid. If you had used the NDEBUG define you would have got a coredump.
Are you trying to write a daemon application and this is the reason for detaching threads?
When main exits, all the global objects are destroyed. Your threads, however, do continue to run. You therefore end up with problems because the threads are accessing a deleted object.
Bottom line is that you must terminate the threads before exiting. The only what to do this though is to get the main program to wait (by using a boost::thread::join) until the threads have finished running. You may want to provide some way of signaling the threads to finish running to save from waiting too long.
The other issue is that your consumer thread continues to run even when there is not data. You might want to wait on a boost::condition_variable until signaled that there is new data.