Conditional variable in multi-threaded application

Lecture



A conditional variable is a synchronization primitive that ensures blocking of one or several streams until a signal is received from another stream about the fulfillment of a certain condition or until the maximum waiting time expires. Conditional variables are used together with the associated mutex and are part of certain types of monitors.

Content
1 Overview
2 Examples of use
2.1POSIX threads
2.2C ++
2.3Qt 4
2.4Python
2.5Ada '95
3Notes


Overview
Conceptually, a conditional variable is a queue of threads associated with a shared data object that are waiting for some condition to be met on the data state. Thus, each condition variable {\ displaystyle c} c is associated with the statement {\ displaystyle P_ {c}} P_c. When a thread is in a wait state on a conditional variable, it is not considered to have data and another thread can change the shared object and signal to the waiting threads if the {\ displaystyle P_ {c}} P_c statement is executed.

Examples of using
The given example illustrates the use of conditional variables to synchronize the flows of the producer and the consumer. The producer stream, gradually increasing the value of the common variable, signals the stream waiting on the conditional variable to fulfill the statement that the maximum value is exceeded. The waiting consumer stream, checking the value of the common variable, is blocked in case of non-fulfillment of the condition of exceeding the maximum. When receiving a signal about the truth of an assertion, the flow “consumes” the shared resource, reducing the value of the common variable so that it does not become less than the permissible minimum.

POSIX threads
In the POSIX threads library for the C language, the functions and data structures with the pthread_cond prefix are responsible for using conditional variables.

C source code using POSIX Threads

#include
#include

#include
#include

#define STORAGE_MIN 10
#define STORAGE_MAX 20

/ * Shared resource * /
int storage = STORAGE_MIN;

pthread_mutex_t mutex;
pthread_cond_t condition;

/ * Consumer flow function * /
void * consumer (void * args)
{
puts ("[CONSUMER] thread started");
int toConsume = 0;

while (1)
{
pthread_mutex_lock (& ​​mutex);
/ * If the value of the shared variable is less than the maximum,
* then the thread enters a state of waiting for a signal of achievement
* maximum * /
while (storage <STORAGE_MAX)
{
pthread_cond_wait (& condition, & mutex);
}
toConsume = storage-STORAGE_MIN;
printf ("[CONSUMER] storage is maximum, consuming% d \ n", \
toConsume);
/ * "Consumption" of allowable volume from total
* variable * /
storage - = toConsume;
printf ("[CONSUMER] storage =% d \ n", storage);
pthread_mutex_unlock (& ​​mutex);
}

return NULL;
}

/ * Manufacturer's flow function * /
void * producer (void * args)
{
puts ("[PRODUCER] thread started");

while (1)
{
usleep (200,000);
pthread_mutex_lock (& ​​mutex);
/ * Manufacturer constantly increases value of common variable * /
++ storage;
printf ("[PRODUCER] storage =% d \ n", storage);
/ * If the value of the shared variable has reached or exceeded.
* maximum consumer flow is notified of this * /
if (storage> = STORAGE_MAX)
{
puts ("[PRODUCER] storage maximum");
pthread_cond_signal (& condition);
}
pthread_mutex_unlock (& ​​mutex);
}
return NULL;
}

int main (int argc, char * argv [])
{
int res = 0;
pthread_t thProducer, thConsumer;

pthread_mutex_init (& mutex, NULL);
pthread_cond_init (& condition, NULL);

res = pthread_create (& thProducer, NULL, producer, NULL);
if (res! = 0)
{
perror ("pthread_create");
exit (EXIT_FAILURE);
}

res = pthread_create (& thConsumer, NULL, consumer, NULL);
if (res! = 0)
{
perror ("pthread_create");
exit (EXIT_FAILURE);
}

pthread_join (thProducer, NULL);
pthread_join (thConsumer, NULL);

return EXIT_SUCCESS;
}
C ++
The C ++ 11 standard has added multithreading support to the language. Work with conditional variables is provided by means declared in the header file condition_variable

Source code in C ++ (C ++ 11)

#include
#include

#include
#include
#include
#include

#define STORAGE_MIN 10
#define STORAGE_MAX 20

int storage = STORAGE_MIN;

std :: mutex globalMutex;
std :: condition_variable condition;

/ * Consumer flow function * /
void consumer ()
{
std :: cout << "[CONSUMER] thread started" << std :: endl;
int toConsume = 0;

while (1)
{
std :: unique_lock lock (globalMutex);
/ * If the value of the shared variable is less than the maximum,
* then the thread enters a state of waiting for a signal of achievement
* maximum * /
if (storage <STORAGE_MAX)
{
condition.wait (lock);
toConsume = storage-STORAGE_MIN;
std :: cout << "[CONSUMER] storage is maximum, consuming"
<< toConsume << std :: endl;
}
/ * "Consumption" of allowable volume from total
* variable * /
storage - = toConsume;
std :: cout << "[CONSUMER] storage =" << storage << std :: endl;
}
}

/ * Manufacturer's flow function * /
void produ


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Operating Systems and System Programming

Terms: Operating Systems and System Programming