LinuxC 线程 -- 条件变量

博客介绍了多线程配合工作时,线程通过条件变量在不满足条件时休眠、满足时被唤醒的机制。条件变量需与互斥锁配合,还说明了其创建步骤,最后给出主线程对变量循环 +1、次线程根据变量值操作的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        多线程配合工作时,当线程检测到某条件不满足时就休眠,直到别的线程将条件准备好,然后通过条件变量将其唤醒。
        条件变量需要在互斥锁的配合下才能工作。

条件变量的创建步骤:

1、定义一个条件变量(全局变量)由于条件变量需要互斥锁的配合,所以还需要定义一个线程互斥锁。

2、初始化条件变量

3、使用条件变量

4、删除条件变量,也需要把互斥锁删除。

主线程对va变量循环+1,次线程发现va==5时,打印va的值并将va清0,如果va的值!=5就什么都不做

代码如下:

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

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <signal.h>

#include <pthread.h>
#include <semaphore.h>

pthread_t ids[2];

int va = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond; // 定义一个条件变量

void my_exit(int sig)
{
    for (int i = 0; i < 2; i++)
    {
        pthread_cancel(ids[i]);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    }
    exit(0);
}

void *thread1(void *arg)
{
    while (1)
    {
        pthread_mutex_lock(&mutex);
        va++;
        if (va == 5)
        {
            // 通知thread2打印,va 清零
            // int pthread_cond_signal(pthread_cond_t * cond);
            // pthread_cond_signal(&cond); // 只能唤醒一个线程
            // int pthread_cond_broadcast(pthread_cond_t * cond);
            pthread_cond_broadcast(&cond); // 广播唤醒所有因为该条件变量睡眠的线程
            /**
             * 功能:当线程将某个数据准备好时,就可以调用该函数去设置cond,表示条件准备好了,
             * pthread_cond_wait检测到cond被设置后就不再休眠(被唤醒),线程继续运行,使用别的线程准备好的数据来做事。
             * 当调用pthread_cond_wait函数等待条件满足的线程只有一个时,就是用pthread_cond_signal来唤醒,
             * 如果说有好多线程都调用pthread_cond_wait在等待时,
             * 使用int pthread_cond_broadcast(pthread_cond_t *cond);
             * 它可以将所有调用pthread_cond_wait而休眠的线程都唤醒。
             */
        }
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}
void *thread2(void *arg)
{
    while (1)
    {
        pthread_mutex_lock(&mutex);
        while (va != 5)
        {
            // 阻塞睡眠 + 释放已加的锁
            // int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
            pthread_cond_wait(&cond, &mutex);
            /**
             * 功能:检测条件变量cond,如果cond没有被设置,表示条件还不满足,别人还没有对cond进行设置,
             * 此时pthread_cond_wait会休眠(阻塞),直到别的线程设置cond表示条件准备好后,才会被唤醒。
             *  返回值:成功返回0,失败返回非零错误号
             * 参数
             *  - cond:条件变量
             *  - mutex:和条件变量配合使用的互斥锁
             */
        }

        printf("va == %d\n", va);
        va = 0;
        pthread_mutex_unlock(&mutex);
    }
}

int main(int argc, char const *argv[])
{
    signal(SIGINT, my_exit); // 释放条件变量
    int ret;
    void *(*p_func[2])(void *) = {thread1, thread2};
    // int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    // 初始化条件变量
    pthread_cond_init(&cond, NULL);
    /**
     * 功能
     * 初始化条件变量,与互斥锁的初始化类似。
     * pthread_cond_init(&cond, NULL); //第二个参数为NULL,表示不设置条件变量的属性。也可以直接初始化:
     *  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//与互斥锁的初始化的原理是一样的
     * 返回值:成功返回0,失败返回非零错误号
     * - cond:条件变量
     * - attr:用于设置条件变量的属性,设置为NULL,表示使用默认属性
     */
    for (int i = 0; i < 2; i++)
    {
        ret = pthread_create(ids + i, NULL, p_func[i], NULL);

        if (ret < 0)
        {
            perror("pthread create error");
            exit(1);
        }
        pthread_detach(ids[i]);
    }

    pause();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值