Check if a thread is finished to send another param to it - c++

I wanna to check if a thread job has been finished to call it again and send another parameter to that. The code is sth like this:
void SendMassage(double Speed)
{
Sleep(200);
cout << "Speed:" << Speed << endl;
}
int main() {
int Speed_1 = 0;
thread f(SendMassage, Speed_1);
for (int i = 0; i < 50; i++)
{
Sleep(20);
if (?)
{
another call of thread // If last thread done then call it again, otherwise not.
}
Speed_1++;
}
}
How should I do it?

Use, e.g., an atomic flag to indicate that the thread has finished:
std::atomic<bool> finished_flag{false};
void SendMassage(double Speed) {
Sleep(200);
cout << "Speed:" << Speed << endl;
finished_flag = true;
}
int main() {
int Speed_1 = 0;
thread f(SendMassage, Speed_1);
while (Speed_1 < 50) {
Sleep(20);
if (finished_flag) {
f.join();
finished_flag = false;
f = std::thread(SendMassage, Speed_1);
}
Speed_1++;
}
f.join();
}
Working example: https://wandbox.org/permlink/BrEMHFvlInshBy5V
Note that I assumed that, according to your code, you don't want to block when checking whether the thread f has finished. Otherwise, simply call f.join().

If you want to wait untill a thread has finished it's job without using Sleep, you neeed to call it's join method, like so
thread t(SendMassage, Speed_1);
t.join();
//Code here will start executing after returning from join
You can read more about it here http://en.cppreference.com/w/cpp/thread/thread/join
About sending another parameter, I think the best way would be splitting it into another function that you would call after this thread has been joined, if you need some information about something that's known only inside the function, you could create a class that would store that information in it's fields, and use it in the function you're threading.

The possibly most simple way of doing so is just joining the thread. Nothing clever, but...
OK, but why would you then want to have another thread at all if your main thread passes all its time sleeping anyway, so you quite sure are looking for something cleverer.
I personally like the principle of queues; you could use e. g. a std::deque for:
Your producer thread places in some values, your consumer thread just takes them out. Of course, you need to protect your queue via a std::mutex (or by other appropriate means) against race conditions...
The consumer would be running in an endless loop, processing the queue, if entries are available, or sleep if this is not the case. Have a look at this response for how to do the waiting...
There is the danger, though, that your queue runs full, so you might define some threshold when you stop or at least slow down producing new values, if you discover your producer being too fast. The queue has another advantage, though: If your producer is too fast, you might have more than one consumer, all serving the same queue (depending on your needs, putting together the results might need some extra efforts to keep ordering of correct).
Admitted, that's quite some work to do, it might be worth the effort, it might be overkill. If simpler approaches fit your needs already, Daniel's answer is fine, too...

Related

is there any way to wakeup multiple threads at the same time in c/c++

well, actually, I'm not asking the threads must "line up" to work, but I just want to notify multiple threads. so I'm not looking for barrier.
it's kind of like the condition_variable::notify_all(), but I don't want the threads wakeup one-by-one, which may cause starvation(also the potential problem in multiple semaphore post operation). it's kind of like:
std::atomic_flag flag{ATOMIC_FLAG_INIT};
void example() {
if (!flag.test_and_set()) {
// this is the thread to do the job, and notify others
do_something();
notify_others(); // this is what I'm looking for
flag.clear();
} else {
// this is the waiting thread
wait_till_notification();
do_some_other_thing();
}
}
void runner() {
std::vector<std::threads>;
for (int i=0; i<10; ++i) {
threads.emplace_back([]() {
while(1) {
example();
}
});
}
// ...
}
so how can I do this in c/c++ or maybe posix API?
sorry, I didn't make this question clear enough, I'd add some more explaination.
it's not thunder heard problem I'm talking about, and yes, it's the re-acquire-lock that bothers me, and I tried shared_mutex, there's still some problem.
let me split the threads to 2 parts, 1 as leader thread, which do the writing job, the others as worker threads, which do the reading job.
but actually they're all equal in programme, the leader thread is the thread that 1st got access to the job( you can take it as the shared buffer is underflowed for this thread). once the job is done, the other workers just need to be notified that them have the access.
if the mutex is used here, any thread would block the others.
to give an example: the main thread's job do_something() here is a read, and it block the main thread, thus the whole system is blocked.
unfortunatly, shared_mutex won't solve this problem:
void example() {
if (!flag.test_and_set()) {
// leader thread:
lk.lock();
do_something();
lk.unlock();
flag.clear();
} else {
// worker thread
lk.shared_lock();
do_some_other_thing();
lk.shared_unlock();
}
}
// outer loop
void looper() {
std::vector<std::threads>;
for (int i=0; i<10; ++i) {
threads.emplace_back([]() {
while(1) {
example();
}
});
}
}
in this code, if the leader job was done, and not much to do between this unlock and next lock (remember they're in a loop), it may get the lock again, leave the worker jobs not working, which is why I call it starve earlier.
and to explain the blocking in do_something(), I don't want this part of job takes all my CPU time, even if the leader's job is not ready (no data arrive for read)
and std::call_once may still not be the answer to this. because, as you can see, the workers must wait till the leader's job finished.
to summarize, this is actually a one-producer-multi-consumer problem.
but I want the consumers can do the job when the product is ready for them. and any can be the producer or consumer. if any but the 1st find the product has run out, the thread should be the producer, thus others are automatically consumer.
but unfortunately, I'm not sure if this idea would work or not
it's kind of like the condition_variable::notify_all(), but I don't want the threads wakeup one-by-one, which may cause starvation
In principle it's not waking up that is serialized, but re-acquiring the lock.
You can avoid that by using std::condition_variable_any with a std::shared_lock - so long as nobody ever gets an exclusive lock on the std::shared_mutex. Alternatively, you can provide your own Lockable type.
Note however that this won't magically allow you to concurrently run more threads than you have cores, or force the scheduler to start them all running in parallel. They'll just be marked as runnable and scheduled as normal - this only fixes the avoidable serialization in your own code.
It sounds like you are looking for call_once
#include <mutex>
void example()
{
static std::once_flag flag;
bool i_did_once = false;
std::call_once(flag, [&i_did_once]() mutable {
i_did_once = true;
do_something();
});
if(! i_did_once)
do_some_other_thing();
}
I don't see how your problem relates to starvation. Are you perhaps thinking about the thundering herd problem? This may arise if do_some_other_thing has a mutex but in that case you have to describe your problem in more detail.

Any case of std::promise that can't be replaced by a single thread running sequential produce-then-consume?

Update 9th June 2020:
Consolidating all the comments and answers here, and putting some more thought to this, I have created a flowchart below (click to zoom) to help decide when to use std::promise/future, and what are the trade-offs.
Original post is as follows:
I have been thinking about the real benefit of the std::promise/future mechanism. Examples almost everywhere tout this pattern - a single producer, single producer scenario where the producer notifies the consumer one-time that the resource in question is ready for consumption:
#include <iostream>
#include <future>
#include <thread>
using namespace std::chrono_literals;
struct StewableFood {
int tenderness;
};
void slow_cook_for_12_hours(std::promise<StewableFood>& promise_of_stew) {
std::cout << "\nChef: Starting to cook ...";
// Cook till 100% tender
StewableFood food{ 0 };
for (int i = 0; i < 10; ++i) {
std::this_thread::sleep_for(10ms);
food.tenderness = (i + 1) * 10;
std::cout << "\nChef: Stewing ... " << food.tenderness << "%";
}
// Notify person waiting on the promise of stew that the promise has been fulfilled.
promise_of_stew.set_value(food);
std::cout << "\nChef: Stew is ready!";
}
void wait_to_eat_stew(std::future<StewableFood>& potenial_fulfilment_of_stew) {
std::cout << "\nJoe: Waiting for stew ...";
auto food = potenial_fulfilment_of_stew.get();
std::cout << "\nJoe: I have been notified that stew is ready. Tenderness " << food.tenderness << "%! Eat!";
}
int main()
{
std::promise<StewableFood> promise_of_stew;
auto potenial_fulfilment_of_stew = promise_of_stew.get_future();
std::thread async_cook(slow_cook_for_12_hours, std::ref(promise_of_stew));
std::thread async_eat(wait_to_eat_stew, std::ref(potenial_fulfilment_of_stew));
async_cook.join();
async_eat.join();
return 0;
}
To me, all this asynchronicity serves no purpose, because ultimately, the consumer's blocking wait on future::get makes this kind of usage equivalent to a single-threaded one with sequential produce-then-consume. I initially thought my example above is contrived. But if we look at the one-time use only constraint of a std::promise/future pair (i.e. you cannot re-write to the original promise nor re-read from the original future), it then follows that the above example becomes the only viable use case, since:
The set-once constraint means there can be only one producer, and
The get-once constraint means there can be only one consumer, and
Inferred from the above 2 set/get-once constraints, there shall be no looping that causes re-use on the same promise/future.
If the usage pattern in the above example is indeed the only viable use case, it then follows that there is no advantage in using std::promise, compared to doing just:
void cook_stew_then_eat() {
auto stew = slow_cook_for_12_hours();
// wait 12 hours
eat_stew(stew);
}
int main() {
std::thread t(cook_stew_then_eat);
t.join();
return 0;
}
Now, this conclusion seems suspicious. I am quite sure there is a good use case for std::promise which cannot be replaced by a single threaded sequential-produce-then-consume version which doesn't involve std::promise.
Question: What is that use case(s)?
Note: It is tempting to speculate that perhaps std::promise/future somehow allows us to asynchronously do something else without waiting on the fulfilment - might that be the advantage? Definitely not, because we can achieve the identical effect by putting that "something else" (e.g. some important work) in another thread. To illustrate:
// cook and eat threads use std::promise/future
std::thread cook(...);
std::thread eat(...);
// Let's do important work on another thread
std::thread important_work(...);
cook.join();
eat.join();
important_work.join();
is identical to this solution that doesn't use std::promise/future:
// sequentially cook then eat, NO NEED to use std::promise/future
std::thread cook_then_eat(...);
// Let's do important work on another thread
std::thread important_work(...);
cook_then_eat.join();
important_work.join();
No, you are actually correct, future/promise pattern can always be replaced with manual thread management (via thread joins, condition variables and mutexes) if you are careful about synchronization and object lifetimes.
The primary benefit of future/promise pattern is abstraction. It hides lifetime management and synchronization of the shared state from you, freeing you from the burden of doing it yourself.
Once the producer has a promise it doesn't need to know anything else about the consuming side, and likewise for the consumer and future. This makes it possible to write more concise, less error prone, and less coupled code.
Also keep in mind that as of C++20 std::future still lacks continuations, which makes it a lot less powerful than it could be.
What is that use case(s)?
Any work that doesn't depend on the result of the promise can be done on other threads before waiting on the promise.
Let's extend your example to a stew competition
extern void slow_cook_for_12_hours(std::promise<StewableFood>& promise_of_stew);
extern Grade rate_stew(const StewableFood &);
std::map<Chef, Grade> judge_stew_competition(std::map<Chef, std::future<StewableFood>>& entries)
{
std::map<Chef, Grade> results;
for (auto & [chef, fut] : entries) { results[chef] = rate_stew(fut.get()); }
return results;
}
int main()
{
std::map<Chef, std::promise<StewableFood>> promises_of_stew = { ... };
std::map<Chef, std::future<StewableFood>> fulfilment_of_stews;
std::vector<std::thread> async_cook;
for (auto & [chef, promise] : promises_of_stew)
{
fulfilment_of_stews[chef] = promise.get_future();
async_cook.emplace(slow_cook_for_12_hours, std::ref(promise));
}
std::thread async_judge(judge_stew_competition, std::ref(fulfilment_of_stews));
for (auto & thread : async_cook) { thread.join(); }
async_judge.join();
return 0;
}
Examples almost everywhere tout this pattern - a single producer, single producer scenario where the producer notifies the consumer one-time that the resource in question is ready for consumption.
May be that is not a good example.
Another example is a task that requires resources/datasets from different providers and there are only blocking calls available to fetch resources (or non-blocking calls cannot easily be integrated into one event loop in your application). In this case your consumer thread launches all resources requests as std::async and waits till they all complete in parallel, rather than sequentially. In this case it takes max(times) rather than sum(times) to fetch all the datasets, where times is an array of each provider response time.

Reusing thread in loop c++

I need to parallelize some tasks in a C++ program and am completely new to parallel programming. I've made some progress through internet searches so far, but am a bit stuck now. I'd like to reuse some threads in a loop, but clearly don't know how to do what I'm trying for.
I am acquiring data from two ADC cards on the computer (acquired in parallel), then I need to perform some operations on the collected data (processed in parallel) while collecting the next batch of data. Here is some pseudocode to illustrate
//Acquire some data, wait for all the data to be acquired before proceeding
std::thread acq1(AcquireData, boardHandle1, memoryAddress1a);
std::thread acq2(AcquireData, boardHandle2, memoryAddress2a);
acq1.join();
acq2.join();
while(user doesn't interrupt)
{
//Process first batch of data while acquiring new data
std::thread proc1(ProcessData,memoryAddress1a);
std::thread proc2(ProcessData,memoryAddress2a);
acq1(AcquireData, boardHandle1, memoryAddress1b);
acq2(AcquireData, boardHandle2, memoryAddress2b);
acq1.join();
acq2.join();
proc1.join();
proc2.join();
/*Proceed in this manner, alternating which memory address
is written to and being processed until the user interrupts the program.*/
}
That's the main gist of it. The next run of the loop would write to the "a" memory addresses while processing the "b" data and continue to alternate (I can get the code to do that, just took it out to prevent cluttering up the problem).
Anyway, the problem (as I'm sure some people can already tell) is that the second time I try to use acq1 and acq2, the compiler (VS2012) says "IntelliSense: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type". Likewise, if I put std::thread in front of acq1 and acq2 again, it says " error C2374: 'acq1' : redefinition; multiple initialization".
So the question is, can I reassign threads to a new task when they have completed their previous task? I always wait for the previous use of the thread to end before calling it again, but I don't know how to reassign the thread, and since it's in a loop, I can't make a new thread each time (or if I could, that seems wasteful and unnecessary, but I could be mistaken).
Thanks in advance
The easiest way is to use a waitable queue of std::function objects. Like this:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <chrono>
class ThreadPool
{
public:
ThreadPool (int threads) : shutdown_ (false)
{
// Create the specified number of threads
threads_.reserve (threads);
for (int i = 0; i < threads; ++i)
threads_.emplace_back (std::bind (&ThreadPool::threadEntry, this, i));
}
~ThreadPool ()
{
{
// Unblock any threads and tell them to stop
std::unique_lock <std::mutex> l (lock_);
shutdown_ = true;
condVar_.notify_all();
}
// Wait for all threads to stop
std::cerr << "Joining threads" << std::endl;
for (auto& thread : threads_)
thread.join();
}
void doJob (std::function <void (void)> func)
{
// Place a job on the queu and unblock a thread
std::unique_lock <std::mutex> l (lock_);
jobs_.emplace (std::move (func));
condVar_.notify_one();
}
protected:
void threadEntry (int i)
{
std::function <void (void)> job;
while (1)
{
{
std::unique_lock <std::mutex> l (lock_);
while (! shutdown_ && jobs_.empty())
condVar_.wait (l);
if (jobs_.empty ())
{
// No jobs to do and we are shutting down
std::cerr << "Thread " << i << " terminates" << std::endl;
return;
}
std::cerr << "Thread " << i << " does a job" << std::endl;
job = std::move (jobs_.front ());
jobs_.pop();
}
// Do the job without holding any locks
job ();
}
}
std::mutex lock_;
std::condition_variable condVar_;
bool shutdown_;
std::queue <std::function <void (void)>> jobs_;
std::vector <std::thread> threads_;
};
void silly (int n)
{
// A silly job for demonstration purposes
std::cerr << "Sleeping for " << n << " seconds" << std::endl;
std::this_thread::sleep_for (std::chrono::seconds (n));
}
int main()
{
// Create two threads
ThreadPool p (2);
// Assign them 4 jobs
p.doJob (std::bind (silly, 1));
p.doJob (std::bind (silly, 2));
p.doJob (std::bind (silly, 3));
p.doJob (std::bind (silly, 4));
}
The std::thread class is designed to execute exactly one task (the one you give it in the constructor) and then end. If you want to do more work, you'll need a new thread. As of C++11, that's all we have. Thread pools didn't make it into the standard. (I'm uncertain what C++14 has to say about them.)
Fortunately, you can easily implement the required logic yourself. Here is the large-scale picture:
Start n worker threads that all do the following:
Repeat while there is more work to do:
Grab the next task t (possibly waiting until one becomes ready).
Process t.
Keep inserting new tasks in the processing queue.
Tell the worker threads that there is nothing more to do.
Wait for the worker threads to finish.
The most difficult part here (which is still fairly easy) is properly designing the work queue. Usually, a synchronized linked list (from the STL) will do for this. Synchronized means that any thread that wishes to manipulate the queue must only do so after it has acquired a std::mutex so to avoid race conditions. If a worker thread finds the list empty, it has to wait until there is some work again. You can use a std::condition_variable for this. Each time a new task is inserted into the queue, the inserting thread notifies a thread that waits on the condition variable and will therefore stop blocking and eventually start processing the new task.
The second not-so-trivial part is how to signal to the worker threads that there is no more work to do. Clearly, you can set some global flag but if a worker is blocked waiting at the queue, it won't realize any time soon. One solution could be to notify_all() threads and have them check the flag each time they are notified. Another option is to insert some distinct “toxic” item into the queue. If a worker encounters this item, it quits itself.
Representing a queue of tasks is straight-forward using your self-defined task objects or simply lambdas.
All of the above are C++11 features. If you are stuck with an earlier version, you'll need to resort to third-party libraries that provide multi-threading for your particular platform.
While none of this is rocket science, it is still easy to get wrong the first time. And unfortunately, concurrency-related bugs are among the most difficult to debug. Starting by spending a few hours reading through the relevant sections of a good book or working through a tutorial can quickly pay off.
This
std::thread acq1(...)
is the call of an constructor. constructing a new object called acq1
This
acq1(...)
is the application of the () operator on the existing object aqc1. If there isn't such a operator defined for std::thread the compiler complains.
As far as I know you may not reused std::threads. You construct and start them. Join with them and throw them away,
Well, it depends if you consider moving a reassigning or not. You can move a thread but not make a copy of it.
Below code will create new pair of threads each iteration and move them in place of old threads. I imagine this should work, because new thread objects will be temporaries.
while(user doesn't interrupt)
{
//Process first batch of data while acquiring new data
std::thread proc1(ProcessData,memoryAddress1a);
std::thread proc2(ProcessData,memoryAddress2a);
acq1 = std::thread(AcquireData, boardHandle1, memoryAddress1b);
acq2 = std::thread(AcquireData, boardHandle2, memoryAddress2b);
acq1.join();
acq2.join();
proc1.join();
proc2.join();
/*Proceed in this manner, alternating which memory address
is written to and being processed until the user interrupts the program.*/
}
What's going on is, the object actually does not end it's lifetime at the end of the iteration, because it is declared in the outer scope in regard to the loop. But a new object gets created each time and move takes place. I don't see what can be spared (I might be stupid), so I imagine this it's exactly the same as declaring acqs inside the loop and simply reusing the symbol. All in all ... yea, it's about how you classify a create temporary and move.
Also, this clearly starts a new thread each loop (of course ending the previously assigned thread), it doesn't make a thread wait for new data and magically feed it to the processing pipe. You would need to implement it a differently like. E.g: Worker threads pool and communication over queues.
References: operator=, (ctor).
I think the errors you get are self-explanatory, so I'll skip explaining them.
I think you need a much more simpler answer for running a set of threads more than once, this is the best solution:
do{
std::vector<std::thread> thread_vector;
for (int i=0;i<nworkers;i++)
{
thread_vector.push_back(std::thread(yourFunction,Parameter1,Parameter2, ...));
}
for(std::thread& it: thread_vector)
{
it.join();
}
q++;
} while(q<NTIMES);
You also could make your own Thread class and call its run method like:
class MyThread
{
public:
void run(std::function<void()> func) {
thread_ = std::thread(func);
}
void join() {
if(thread_.joinable())
thread_.join();
}
private:
std::thread thread_;
};
// Application code...
MyThread myThread;
myThread.run(AcquireData);

when to use mutex

Here is the thing: there is a float array float bucket[5] and 2 threads, say thread1 and thread2.
Thread1 is in charge of tanking up the bucket, assigning each element in bucket a random number. When the bucket is tanked up, thread2 will access bucket and read its elements.
Here is how I do the job:
float bucket[5];
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1, thread2;
void* thread_1_proc(void*); //thread1's startup routine, tank up the bucket
void* thread_2_proc(void*); //thread2's startup routine, read the bucket
int main()
{
pthread_create(&thread1, NULL, thread_1_proc, NULL);
pthread_create(&thread2, NULL, thread_2_proc, NULL);
pthread_join(thread1);
pthread_join(thread2);
}
Below is my implementation for thread_x_proc:
void* thread_1_proc(void*)
{
while(1) { //make it work forever
pthread_mutex_lock(&mu); //lock the mutex, right?
cout << "tanking\n";
for(int i=0; i<5; i++)
bucket[i] = rand(); //actually, rand() returns int, doesn't matter
pthread_mutex_unlock(&mu); //bucket tanked, unlock the mutex, right?
//sleep(1); /* this line is commented */
}
}
void* thread_2_proc(void*)
{
while(1) {
pthread_mutex_lock(&mu);
cout << "reading\n";
for(int i=0; i<5; i++)
cout << bucket[i] << " "; //read each element in the bucket
pthread_mutex_unlock(&mu); //reading done, unlock the mutex, right?
//sleep(1); /* this line is commented */
}
}
Question
Is my implementation right? Cuz the output is not as what I expected.
...
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
tanking
tanking
tanking
tanking
...
But if I uncomment the sleep(1); in each thread_x_proc function, the output is right, tanking and reading follow each other, like this:
...
tanking
reading
1.80429e+09 8.46931e+08 1.68169e+09 1.71464e+09 1.95775e+09 4.24238e+08 7.19885e+08
tanking
reading
1.64976e+09 5.96517e+08 1.18964e+09 1.0252e+09 1.35049e+09 7.83369e+08 1.10252e+09
tanking
reading
2.0449e+09 1.96751e+09 1.36518e+09 1.54038e+09 3.04089e+08 1.30346e+09 3.50052e+07
...
Why? Should I use sleep() when using mutex?
Your code is technically correct, but it does not make a lot of sense, and it does not do what you assume.
What your code does is, it updates a section of data atomically, and reads from that section, atomically. However, you don't know in which order this happens, nor how often the data is written to before being read (or if at all!).
What you probably wanted is generate exactly one sequence of numbers in one thread every time and read exactly one new sequence each time in the other thread. For this, you would use either have to use an additional semaphore or better a single-producer-single-consumer queue.
In general the answer to "when should I use a mutex" is "never, if you can help it". Threads should send messages, not share state. This makes a mutex most of the time unnecessary, and offers parallelism (which is the main incentive for using threads in the first place).
The mutex makes your threads run lockstep, so you could as well just run in a single thread.
There is no implied order in which threads will get to run. This means you shall not expect any order. What's more it is possible to get on thread running over and over without letting the other to run. This is implementation specific and should be assumed random.
The case you presented falls much rather for a semaphor which is "posted" with each element added.
However if it has always to be like:
write 5 elements
read 5 elements
you should have two mutexes:
one that blocks producer until the consumer finished
one that blocks consumer until the producer finished
So the code should look something like that:
Producer:
while(true){
lock( &write_mutex )
[insert data]
unlock( &read_mutex )
}
Consumer:
while(true){
lock( &read_mutex )
[insert data]
unlock( &write_mutex )
}
Initially write_mutex should be unlocked and read_mutex locked.
As I said your code seems to be a better case for semaphores or maybe condition variables.
Mutexes are not meant for cases such as this (which doesn't mean you can't use them, it just means there are more handy tools to solve that problem).
You have no right to assume that just because you want your threads to run in a particular order, the implementation will figure out what you want and actually run them in that order.
Why shouldn't thread2 run before thread1? And why shouldn't each thread complete its loop several times before the other thread gets a chance to run up to the line where it acquires the mutex?
If you want execution to switch between two threads in a predictable way, then you need to use a semaphore, condition variable, or other mechanism for messaging between the two threads. sleep appears to result in the order you want on this occasion, but even with the sleep you haven't done enough to guarantee that they will alternate. And I have no idea why the sleep makes a difference to which thread gets to run first -- is that consistent across several runs?
If you have two functions that should execute sequentially, i.e. F1 should finish before F2 starts, then you shouldn't be using two threads. Run F2 on the same thread as F1, after F1 returns.
Without threads, you won't need the mutex either.
It isn't really the issue here.
The sleep only lets the 'other' thread access the mutex lock (by chance, it is waiting for the lock so Probably it will have the mutex), there is no way you can be sure the first thread won't re-lock the mutex though and let the other thread access it.
Mutex is for protecting data so two threads don't :
a) write simultaneously
b) one is writing when another is reading
It is not for making threads work in a certain order (if you want that functionality, ditch the threaded approach or use a flag to tell that the 'tank' is full for example).
By now, it should be clear, from the other answers, what are the mistakes in the original code. So, let's try to improve it:
/* A flag that indicates whose turn it is. */
char tanked = 0;
void* thread_1_proc(void*)
{
while(1) { //make it work forever
pthread_mutex_lock(&mu); //lock the mutex
if(!tanked) { // is it my turn?
cout << "tanking\n";
for(int i=0; i<5; i++)
bucket[i] = rand(); //actually, rand() returns int, doesn't matter
tanked = 1;
}
pthread_mutex_unlock(&mu); // unlock the mutex
}
}
void* thread_2_proc(void*)
{
while(1) {
pthread_mutex_lock(&mu);
if(tanked) { // is it my turn?
cout << "reading\n";
for(int i=0; i<5; i++)
cout << bucket[i] << " "; //read each element in the bucket
tanked = 0;
}
pthread_mutex_unlock(&mu); // unlock the mutex
}
}
The code above should work as expected. However, as others have pointed out, the result would be better accomplished with one of these two other options:
Sequentially. Since the producer and the consumer must alternate, you don't need two threads. One loop that tanks and then reads would be enough. This solution would also avoid the busy waiting that happens in the code above.
Using semaphores. This would be the solution if the producer was able to run several times in a row, accumulating elements in a bucket (not the case in the original code, though).
http://en.wikipedia.org/wiki/Producer-consumer_problem#Using_semaphores

How can I tell reliably if a boost thread has exited its run method?

I assumed joinable would indicate this, however, it does not seem to be the case.
In a worker class, I was trying to indicate that it was still processing through a predicate:
bool isRunning(){return thread_->joinable();}
Wouldn't a thread that has exited not be joinable? What am I missing... what is the meaning of boost thread::joinable?
Since you can join a thread even after it has terminated, joinable() will still return true until you call join() or detach(). If you want to know if a thread is still running, you should be able to call timed_join with a wait time of 0. Note that this can result in a race condition since the thread may terminate right after the call.
Use thread::timed_join() with a minimal timeout. It will return false if the thread is still running.
Sample code:
thread_->timed_join(boost::posix_time::seconds(0));
I am using boost 1.54, by which stage timed_join() is being deprecated. Depending upon your usage, you could use joinable() which works perfectly for my purposes, or alternatively you could use try_join_for() or try_join_until(), see:
http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html
You fundamentally can't do this. The reason is that the two possible answers are "Yes" and "Not when I last looked but perhaps now". There is no reliable way to determine that a thread is still inside its run method, even if there was a reliable way to determine the opposite.
This is a bit crude but as of now it's still working for my requirements. :) I'm using boost 153 and qt. I created a vector of int for tracking the "status" of my threads. Every time I create a new thread, I add one entry to thread_ids with a value of 0. For each thread created, I pass an ID so I know what part of thread_ids I'm supposed to update. Set the status to 1 for running and other values depending on what activity I am currently doing so I know what activity was being done when the thread ended. 100 is the value I set for a properly finished thread. I'm not sure if this will help but if you have other suggestions on how to improve on this let me know. :)
std::vector<int> thread_ids;
const int max_threads = 4;
void Thread01(int n, int n2)
{
thread_ids.at(n) = 1;
boost::this_thread::sleep(boost::posix_time::milliseconds(n2 * 1000));
thread_ids.at(n) = 100;
qDebug()<<"Done "<<n;
}
void getThreadsStatus()
{
qDebug()<<"status:";
for(int i = 0; i < max_threads, i < thread_ids.size(); i++)
{
qDebug()<<thread_ids.at(i);
}
}
int main(int argc, char *argv[])
{
for(int i = 0; i < max_threads; i++)
{
thread_ids.push_back(0);
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService));
ioService.post(boost::bind(Thread01, i, i + 2));
getThreadsStatus();
}
ioService.stop();
threadpool.join_all();
getThreadsStatus();
}
The easiest way, if the function that is running your thread is simple enough, is to set a variable to true when the function is finished. Of course, you will need a variable per thread, if you have many a map of thread ids and status can be a better option. I know it is hand made, but it works fine in the meanwhile.
class ThreadCreator
{
private:
bool m_threadFinished;
void launchProducerThread(){
// do stuff here
m_threadRunning = true;
}
public:
ThreadCreator() : m_threadFinished(false) {
boost::thread(&Consumer::launchProducerThread, this);
}
};
This may not be a direct answer to your question, but I see the thread concept as a really light-weight mechanism, and intentionally devoid of anything except synchronization mechanisms. I think that the right place to put "is running" is in the class that defines the thread function. Note that from a design perspective, you can exit the thread on interrupt and still not have your work completed. If you want to clean up the thread after it's completed, you can wrap it in a safe pointer and hand it to the worker class.