Conditional variables allow us to sleep and wait for certain conditions to appear. (In windows, the interlock function can be used to simulate the conditional variables in linux)
A condition variable is a mechanism for synchronizing global variables shared by threads. It mainly includes two actions: one thread waits for the condition variable to be established and suspends; another thread sets "condition to true" (a signal indicating condition to true ).
To prevent competition, the use of condition variables is always combined with a mutex lock.
The condition variable type is pthread_cond _
Like mutex lock, conditional variables have two static and dynamic creation methods:
Use the PTHREAD_COND_INITIALIZER constant in static mode, as follows: pthread_cond_t cond = PTHREAD_COND_INITIALIZER
Call the pthread_cond_init () function dynamically. The API is defined as follows: int pthread_cond_init (pthread_cond_t * cond, pthread_condattr_t * cond_attr). Although the POSIX standard defines attributes for condition variables, they are not implemented in Lin, therefore, the cond_attr value is usually NULL and ignored.
To cancel a condition variable, you must call pthread_cond_destroy (). This condition variable can be canceled only when no thread is waiting for the condition variable. Otherwise, EBUSY is returned. The API is defined as follows: int pthread_cond_destroy (pthread_cond_t * cond)
The following is the code for using conditional variables extracted from a program written by a bird:
#include <stdlib.h>#include <queue>#include <pthread.h>struct InitIndexTask{int x;int y;int z;InitIndexTask(int a, int b, int c){this->x = a;this->y = b;this->z = c;}};/*******global variables******/const uint8_t THREAD_COUNT = 8;pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t condition_init = PTHREAD_COND_INITIALIZER;queue<InitIndexTask*> InitIndexQ;/*******init thread body******/void* InitIndexThread(void* data){char* thread_name = (char*)data;cout << "created an init_index_thread(tid:" << (unsigned int)pthread_self() << " tname:" << thread_name << ")." << endl;InitIndexTask* initTask = NULL;while (true){pthread_mutex_lock( &init_mutex );while (InitIndexQ.empty())pthread_cond_wait( &condition_init, &init_mutex );initTask = InitIndexQ.front();InitIndexQ.pop();pthread_mutex_unlock( &init_mutex );if (!initTask)break;//...delete initTask;}cout << thread_name << " exited." << endl;delete[] BUFF;delete[] thread_name;}/******* main******/int main(int argc, char** argv){pthread_t* threadArr = new pthread_t[THREAD_COUNT];for (uint8_t i = 0; i < THREAD_COUNT; ++i){char* thread_name = new char[50];snprintf(thread_name, 50, "Thread-%d", i);pthread_create(&threadArr[i], 0, &InitIndexThread, thread_name);}for (int i = 0; i < 100; i++) {InitIndexTask* task = new InitIndexTask(i, 2*i, 3*i);pthread_mutex_lock( &init_mutex );InitIndexQ.push(task);pthread_mutex_unlock( &init_mutex );pthread_cond_signal( &condition_init );}for (uint8_t i = 0; i < THREAD_COUNT; ++i){pthread_mutex_lock( &init_mutex );InitIndexQ.push(NULL);pthread_mutex_unlock( &init_mutex );pthread_cond_signal( &condition_init );}for (uint8_t i = 0; i < THREAD_COUNT; ++i)pthread_join(threadArr[i], NULL);delete[] threadArr;cout << "main thread exited." << endl;}