条件变量中pthread_cond_wait函数

首先看一个生产者和消费者实例,主线程作为生产者,它先创建很多消费者线程,再给队列中放入产品

#include <bits/stdc++.h>
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace st d;

static pthread_mutex_t g_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
static queue<int> g_queue;

static void *thread_func(void *arg)
{
    pthread_mutex_lock(&g_mtx);
    while (g_queue.empty())
    {
        pthread_cond_wait(&g_cond, &g_mtx);
    }
    int val = g_queue.front();
    g_queue.pop();
    cout << "ThreadID:" << pthread_self() << " Get front queue:" << val << endl;
    pthread_mutex_unlock(&g_mtx);
    return 0;
}

int main()
{
    int threadNum = 10;
    pthread_t tids[threadNum];

    int maxNum = 10;

    for (int i = 0; i < threadNum; i++)
    {
        pthread_create(tids + i, NULL, thread_func, NULL);
    }

    for (int i = 0; i < maxNum; i++) //主线程作为生产者
    {
        pthread_mutex_lock(&g_mtx);
        g_queue.push(i);
        pthread_cond_signal(&g_cond);
        pthread_mutex_unlock(&g_mtx);
    }

    for (int i = 0; i < threadNum; i++) //主线程执行完回收
    {
        pthread_join(tids[i], NULL);
    }
    cout << "Main exit!" << endl;
    return 0;
}

运行结果:

ThreadID:139923478742784 Get front queue:0
ThreadID:139923554830080 Get front queue:1
ThreadID:139923546375936 Get front queue:2
ThreadID:139923537921792 Get front queue:3
ThreadID:139923529467648 Get front queue:4
ThreadID:139923521013504 Get front queue:5
ThreadID:139923512559360 Get front queue:6
ThreadID:139923504105216 Get front queue:7
ThreadID:139923495651072 Get front queue:8
ThreadID:139923487196928 Get front queue:9
Main exit!

可以看到条件变量主要用于共享数据状态变化的通信, 当一个线程依赖于另一个线程,而另一个线程对它们的共享数据做了改变后,通知激活这个线程。

​ 条件变量是与互斥量相关联的一种用于多线程之间关于共享数据状态改变的通信机制。需要和互斥锁配合使用,防止多个线程同时请求pthread_cond_wait的静态条件,mutex互斥锁必须是普通锁PTHREAD_MUTEX_TIMED_NP或者适应锁PTHREAD_MUTEX_ADAPTIVE_NP

​ 调用pthread_cond_wait前必须由本线程加锁,调用pthread_cond_wait时,有两个操作:1. 调用线程放到条件等待队列上。2. Mutex解锁。因为只有解锁了,生产者线程才能去改变条件。而这两步必须是原子操作不可分割,然后多个线程进入条件等待队列,当有另一个线程调用pthread_cond_signal时,pthread_cond_wait获得mutex后返回,这里只有一个线程获取了mutex,其他线程依旧是pthread_cond_wait状态,这次加锁刚好对应了在pthread_cond_wait之前的加锁动作。

​ 激发条件是:pthread_cond_signal激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast则激活所有等待线程。

posted @ 2020-09-19 20:59  WindSun  阅读(301)  评论(0)    收藏  举报
博客已停更,文章已转移,点击访问