多线程(2)-线程同步条件变量

在 Linux 多线程编程中,条件变量是一种用于线程间同步的重要机制。它通常与互斥锁结合使用,用于解决多个线程竞争共享资源的问题。条件变量允许一个线程在等待某个条件变为真时阻塞,并且在另一个线程改变条件并通知时恢复执行。这个玩意跟内核等待队列差不多意思。
 
在 Linux 多线程编程中,使用条件变量进行线程同步通常涉及以下几个相关的函数:
pthread_cond_init: 该函数用于初始化条件变量。
原型为 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)。
参数 cond 是要初始化的条件变量,attr 是条件变量的属性,通常为 NULL。

pthread_cond_destroy: 用于销毁条件变量。
原型为 int pthread_cond_destroy(pthread_cond_t *cond)。
参数 cond 是要销毁的条件变量。

pthread_cond_wait: 该函数用于等待条件变量的状态发生变化。
原型为 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)。
参数 cond 是要等待的条件变量,mutex 是与条件变量配合使用的互斥锁。在调用该函数时,线程会释放互斥锁并阻塞,直到条件变量被其他线程发出信号唤醒。

pthread_cond_timedwait: 类似于 pthread_cond_wait,但是可以设置超时时间,防止永久等待。
原型为 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)。

pthread_cond_signal: 该函数用于发送信号给等待条件变量的一个线程。
原型为 int pthread_cond_signal(pthread_cond_t *cond)。调用该函数会唤醒等待队列中的一个线程。

pthread_cond_broadcast: 类似于 pthread_cond_signal,但会唤醒等待队列中的所有线程。
原型为 int pthread_cond_broadcast(pthread_cond_t *cond)。
 

条件变量demo:

在此demo中,有一个生产者线程和一个消费者线程,它们共享一个整数变量 shared_data。生产者线程周期性地增加 shared_data 的值,而消费者线程在 shared_data 不为零时消费一个数据。生产者在生产了一个数据后会发送信号通知消费者线程,消费者在消费数据时需要先检查条件是否满足,如果不满足,则等待条件变为真。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int shared_data = 0;

void* producer(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        shared_data++; // 生产一个数据
        printf("Produced: %d\n", shared_data);
        pthread_cond_signal(&cond); // 发送信号通知消费者
        pthread_mutex_unlock(&mutex);
        sleep(1); // 生产者休眠1秒
    }
    return NULL;
}

void* consumer(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (shared_data == 0) { // 等待条件变为真
            pthread_cond_wait(&cond, &mutex);
        }
        printf("Consumed: %d\n", shared_data);
        shared_data--; // 消费一个数据
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t producer_thread, consumer_thread;
    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);
    return 0;
}
 

条件变量demo执行结果:

0
 
 
 
 
 
 
posted @ 2024-04-04 07:46  lethe1203  阅读(1)  评论(0编辑  收藏  举报