简体   繁体   中英

Synchronise 3 threads with 3 condition variables

I'm writing a program in c++ in a vtk/QT environment. This problem, however, is mostly a question of approach/algorithm.

I am stuck in an attempt to synchronise my three running threads: 1. thread: transmit one sample at a time, and adds it to a "output" buffer 2. thread: receives one sample at a time, and adds it to a "input" buffer 3. thread: pulls data from "output" and "input" buffers and ads them to separate plotting buffers, for rendering.

I want these threads to be run synchronised, and have there-for tried an approach where I use one condition variable together with a boolian condition for each of the threads, where one thread signals to the next and so fourth in a loop, in the order listed above. However, when I do this I get a deadlock and my program stops. I would really appreciate some input here:)

Here's my approach in code:

//Initialcondition for the boolian variables:

readyForTransmit=true;
readyForReceive=false;
readyForPlotting=false;

Thread 1 - transmit:

while(1){
mutex->Lock();
//waits for condition/signal to proceed
while(!readyForTransmit)
    transmitConditionVariable->wait(mutex);
readyForTransmit=false;
mutex->Unlock();

//Here I transmit my sample
transmit();

//Triggers next thread - reception
mutex->Lock();
readyForReceive=true;
receiveConditionVariable->broadcast(); //Have also tried signal();
mutex->Unlock();
}

Thread 2 - receive:

while(1){
mutex->Lock();
//waits for condition/signal to proceed
while(!readyForReceive)
    receiveConditionVariable->wait(mutex);
readyForReceive=false;
mutex->Unlock();

//Here I receive my sample
receive();

//Triggers next thread - reception
mutex->Lock();
readyForPlotting=true;
plottingConditionVariable->broadcast(); //Have also tried signal();
mutex->Unlock();
}

Thread 3 - adds to plotting buffers:

while(1){
mutex->Lock();
//waits for condition/signal to proceed
while(!readyForPlotting)
    plottingConditionVariable->wait(mutex);
readyForPlotting=false;
mutex->Unlock();

//Here I adds samples to plotting buffer
updatePlottingBuffers();

//Triggers next thread - reception
mutex->Lock();
readyForTransmit=true;
transmitConditionVariable->broadcast(); //Have also tried signal();
mutex->Unlock();
}

In addition to this I push and pull samples thread-safe to and from the buffers. So that shouldn't be a problem.

Hope to hear from you! =)

  1. Quick answer: Don't wait for the variables to be true when you already have the lock. If the readyForTransmit is not true after entering the mutex->Lock() area, it never will be, because none of the other threads can enter their mutex->Lock() area to set it.

  2. You seem to synchronize the threads so that you always transmit exactly ONE item, THEN receive exactly one, THEN plot it. That is no parallel behaviour and you could just put them together in one thread, which would be easier and more efficient.

  3. I will assume that this is just test code and you will want to, like, transmit multiple items into the buffer without waiting for the plot thread. In this case your problem looks exactly like the consumer-producer-problem, the textbook-example for using semaphores for synchronization. You can find several possible solutions on this Wikipedia-Page: https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem or you can just google for Consumer-Producer and you will find many good answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM