Linux Posix线程条件变量

生产者消费者模型
1.多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量)
2.调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在某一个条件上等待
--pthread_cond_wait()函数的本质是①:拿到锁的线程,把锁暂时丢掉(解锁)②:线程休眠,进行等待③:线程等待通知,醒来继续执行(重新获得锁)
--这个pthread_cond_wait()函数是一个原子性操作
--注意:丢掉的锁可以被生产线程获得,也可以被消费线程获得,消费者线程获取会陷入等待,生产者线程获得会发送信号,唤醒消费者
3.pthread_cond_signal()生产者拿到锁,生产n,生产完成后,发送信号给消费者(唤醒消费者),生产者离开临界区
//生产者消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>

//定义线程锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//定义线程条件锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//定义全局变量
int g_num = 0;

//定义消费者线程数量
#define Consume_Count 2

//定义生产者线程数量
#define Product_Count 4

//消费者线程
void *consume_run(void * arg)
{
    int tnum = (int) arg;
    while (1)
    {
        //因为多线程操作一个全局变量,需要做成临界区,枷锁
        pthread_mutex_lock(&mutex);
        printf("消费者%d进入临界区!\n", tnum);
        //因为就算消费者被唤醒,也需要重新检查g_num的值,因为pthread_cond_wait()函数丢锁之后,可能被其他消费者获得
        //导致多个消费者线程都执行了pthread_cond_wait()函数陷入等待,
        //因为多个消费者线程被pthread_cond_signal()唤醒,但是资源只有一个,可能已经被其他消费者使用了
        //pthread_cond_wait()也有可能被其他信号唤醒
        //所以需要重新判断,而不能使用if
        while (g_num == 0)
        {
            printf("消费者%d开始等待!\n", tnum);
            //在该线程锁上,进行条件等待
            pthread_cond_wait(&cond, &mutex);
            printf("消费者%d被唤醒!\n", tnum);
        }
        //表示已经有资源了,可以消费了
        printf("消费者%d开始消费!\n", tnum);
        g_num--;
        //解锁
        pthread_mutex_unlock(&mutex);
        sleep(3);
    }
    return NULL;
}

//生产者线程
void *product_run(void * arg)
{
    int tnum = (int) arg;
    while (1)
    {
        //当生产者大于消费者时,可能出现生产过多的商品,需要对商品的上限做一个限制,如果商品过多,需要让生产者睡眠
        //涉及到对全局变量的访问,需要加锁
        printf("现有资源个数%d!\n",g_num);
        pthread_mutex_lock(&mutex);
        if (g_num > 20)
        {
            printf("生产者%d产品已经到达上限,进入睡眠!\n", tnum);
            //如果生产产品大于上限,需要睡眠,但是睡眠前应该将锁释放.,留给消费者进行消费
            pthread_mutex_unlock(&mutex);
            sleep(3);
            continue;
        } else
        {
            printf("生产者%d生产产品!\n", tnum);
            //如果生产产品小于上限,那么不需要生产者睡眠,接着生产产品
            g_num++;
            //发送条件信号
            printf("生产者%d发送条件信号!\n", tnum);
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
        }
        pthread_mutex_unlock(&mutex);
        sleep(2);
    }
    return NULL;
}

int main(int arg, char * args[])
{
    pthread_t thrs[Consume_Count + Product_Count];
    int i = 0;
    for (i = 0; i < Consume_Count; i++)
    {
        if (pthread_create(&thrs[i], NULL, consume_run, (void *) i) != 0)
        {
            printf("pthread_create() failed !\n");
            return -1;
        }
    }
    for (i = 0; i < Product_Count; i++)
    {
        if (pthread_create(&thrs[i + Consume_Count], NULL, product_run,
                (void *) i) != 0)
        {
            printf("pthread_create() failed !\n");
            return -1;
        }
    }
    //join
    for (i = 0; i < Consume_Count + Product_Count; i++)
    {
        if (pthread_join(thrs[i], NULL) != 0)
        {
            printf("pthread_join() failed !\n");
            break;
        }
    }
    printf("进程推出了!\n");
    return 0;
}
时间: 2024-10-04 08:24:29

Linux Posix线程条件变量的相关文章

Linux 线程 条件变量

下面是一个多线程,生产者消费者问题,一个队列放暂存的数据: 1 #include <iostream> 2 #include <queue> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <pthread.h> 6 7 using std::cout; 8 using std::endl; 9 using std::queue; 10 11 #define N 100 12 #def

Linux线程条件变量成为取消点的陷阱

Linux线程条件变量成为取消点的陷阱 使用 pthread_cancel() 时,线程往往不会直接退出,而需要运行到取消点. pthread_cond_wait() 作为线程常见的一种阻塞,它也是一个取消点.所以,处于条件变量阻塞的线程在接收到取消信号就会直接退出. 然而,由于条件变量需要搭配互斥量使用,进入 pthread_cond_wait() 意味着互斥量上锁,此时退出线程如果不进行解锁,而且同时其他线程正在等待此条件变量,那么就会陷入死锁.因此建议使用cleanup函数在线程退出时对互

Linux posix线程库总结

由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 目前,pthreads的实现有3种方式: (1)第一,多对一,也就是库实现. (2)第二种,1:1模式. 1:1模式适合CPU密集型的机器.我们知道,进程(线程)在运行中会由于等待某种资源而阻塞,可能是I/O资源,也可能是CPU.在多CPU机器上1:1模式是个很不错的选择.因此1:1的优点就是,能够充分发挥SMP的优势. 这种模式也有它的缺

linux多线程-互斥&amp;条件变量与同步

多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int g_val = 10; void * test1(void* args) { g_val = 20; printf(&

Linux互斥量&amp;条件变量

互斥量 Mutex 互斥量1. #include <pthread.h>  2. int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);  3.   4. int pthread_mutex_lock(pthread_mutex_t *mutex);  5.   6. int pthread_mutex_unlock(pthread_mutex_t *mutex);  7.   

Linux多线程编程-条件变量

条件变量 如果说线程间的互斥锁是用来同步共享数据的访问的话,那么条件变量是用于线程之间共享数据的值.条件变量提供了一种线程之间的通知机制,当某个共享数据达到某个值时,唤醒等待这个共享数据的线程.条件变量相关函数主要 有5个: #include <pthread.h> int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr); int pthread_cond_destroy(pthread_

Linux Condition Variable条件变量避免锁冲突

条件变量Condition Variable的一般用法: 唤醒用法: 1 struct { 2 pthread_mutex_t mutex; 3 pthread_cond_t cond; 4 //whatever variables maintain the condition 5 ) var = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, ... };//声明结构体并初始化 6 7 pthread_mutex_lock(&var

linux多线程:条件变量

转自 http://blog.csdn.net/hongmy525/article/details/5194006 #include <pthread.h>#include <stdio.h>#include <stdlib.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/void

Linux下用条件变量实现多线程间生产者与消费者问题

一. 线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在pthread库中通过条件变量(Condition Variable)来阻塞等待某个条件,或者唤醒等待这个条件的线程.Condition Variablepthread_cond_t类型的变量表,可以这样初始化和销毁: 返回值:成功返回0,失败返回错误号. 一个Condition Variable总是和一个Mutex搭配使