Conditional variables for Linux multithreaded programming

Posted by AcidRain on Fri, 03 Sep 2021 22:56:00 +0200

preface

Condition variable is a mechanism for synchronization by using global variables shared among threads. It mainly includes two actions: a thread waits for "the condition of condition variable is established" and hangs; Another thread makes the "condition true" (gives the condition true signal). To prevent contention, the use of conditional variables is always combined with a mutex.

1. Function description

a,pthread_ cond_ The init function can be used to initialize a condition variable. It initializes a condition variable with the attribute specified by the variable attr. If the parameter attr is empty, it will use the default attribute to set the specified condition variable.
  
  b,pthread_ cond_ The destroy function can be used to destroy the specified condition variable and release the allocated resources. The process calling the function does not need to wait on the condition variable specified by the parameter.

  c,pthread_cond_timedwait function and thread_cond_wait functions are used to wait for conditions to be met. The difference is pthread_ cond_ If the timedwait function reaches or exceeds the referenced argument abstime, it ends and returns the error ETIME. pthread_ cond_ The process executed by wait first unlocks the mutex, and then waits for the condition variable to be awakened. If it is not awakened, the thread will always sleep, that is, the thread will always block the pthread_ cond_ In the wait call, when the thread is awakened, first judge whether the condition variable is true. If not, continue to sleep and wait for the next activation. If true, lock the mutex and exit. That is, pthread_ cond_ In fact, wait can be regarded as a combination of the following actions: (1) unlock the thread lock( 2) Wait for the thread to wake up, and the condition is true( 3) Lock thread lock

  pthread_ cond_ The parameter abstime of the timedwait function points to a timespec structure. The structure is as follows:

typedef struct timespec {
    time_t tv_sec;
    long tv_nsex;
}timespec_t;

d. When pthread is called_ cond_ Signal, a thread blocked on the same condition variable will be unlocked. If there are multiple threads blocking at the same time, the scheduling policy determines the thread receiving the notification. If pthread is called_ cond_ Broadcast, all threads blocked on this condition variable will be notified. Once awakened, the thread will still require a mutex. If no thread is currently waiting for notification, both calls actually become an empty operation. If the parameter * cond points to an illegal address, the value EINVAL is returned. pthread_cond_signal is only responsible for waking up a thread that is blocking on the same condition variable. If there are multiple threads, the system automatically decides to wake up one of them according to the scheduling policy. On multiprocessors, this function may wake up multiple threads at the same time. At the same time, this function has nothing to do with the lock operation. The unlocking is performed by pthread_ mutex_ Unlock & mutex completed.

2. Use examples

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*Initialize mutex*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*Initialize condition variable*/

void *thread1(void *);
void *thread2(void *);

int i=1;
int main(void)
{
    pthread_t t_a;
    pthread_t t_b;

    pthread_create(&t_a,NULL,thread2,(void *)NULL);/*Create process t_a*/
    pthread_create(&t_b,NULL,thread1,(void *)NULL); /*Create process t_b*/
    pthread_join(t_b, NULL);/*Waiting for process t_b end*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    exit(0);
}

void *thread1(void *junk)
{
    for(i=1;i<=9;i++) 
    {
        pthread_mutex_lock(&mutex);/*Lock mutex*/
        if(i%3==0)
             pthread_cond_signal(&cond);/*Condition change, send signal, notify t_b process*/
        else        
             printf("thead1:%d/n",i);
        pthread_mutex_unlock(&mutex);/*Unlock mutex*/

        sleep(1);
    }

}

void *thread2(void *junk)
{
    while(i<9)
    {
        pthread_mutex_lock(&mutex);

        if(i%3!=0) {
            pthread_cond_wait(&cond,&mutex);/*wait for*/
        }
        printf("thread2:%d/n",i);
        pthread_mutex_unlock(&mutex);

        sleep(1);
    }
}

#cc –lpthread –o cond cond.c

#./cond

thread1:1

thread1:2

thread2:3

thread1:4

thread1:5

thread2:6

thread1:7

thread1:8

thread2:9

Topics: Python Linux perl