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

原创 2018年04月15日 00:07:03
条件变量(cond):

为什么需要条件变量?

  1. 当一个线程互斥的访问某个变量时,它可能发现在其他线程改变该变量状态之前,它什么也做不了!(此时就是死锁,一种僵死状态)

我们需要一种机制,当互斥量锁住以后,当前线程还是无法完成自己的操作,那么就应该释放互斥量,让其他线程继续工作。
1. 可以用轮询机制,不停的查询你需要的条件;
2. 用条件变量机制;

条件变量函数:
(1)初始化

函数初始化
int pthread_cond_init(pthread_cond_t *restrict cont,const pthread_condattr_t *restrict attr);

参数:跟互斥量相似
cond: 要初始化的条件变量;
attr: 条件变量属性,一般设为NULL;
当然也可以用宏 : PTHREAD_CONT_INITALIZER 静态初始化

pthread_cond_t cond = PTHREAD_CONT_INITALIZER;

(2)等待条件满足

//非阻塞,
int pthread_cond_timedwite(pthread_conda_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
//阻塞
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

参数:
cond: 要在这个条件变量上等待;
mutex: 互斥量
abstime: 指定等待时间,如果在规定时间没有通知,返回 ETIMEDOUT错误;
pthread_cond_wait()做的三件事:
1,释放锁—->2,等待锁—->3,收到条件信息,尝试获取锁

(3)唤醒等待

//唤醒改条件变量上的所有线程
int pthread_cond_broadcast(pthread_cond_t *cond);
//至少唤醒一个等待的线程
int pthread_cond_signal(pthread_cond_t *cond);

(4)销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond);

例子:
有全局变量money;主线程减小money,当money等于0时,子线程使money加上200;

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

pthread_cond_t cond;    //定义条件变量
pthread_mutex_t mutex;  //定义互斥量

int money;  //定义全局资源
//线程函数
void* pthread_func(void* arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex); //上锁

        while(money>0)
        {
            printf("让子线程等待money等于0\n");
            pthread_cond_wait(&cond,&mutex);    //等待(阻塞)
        }

        //让子线程进入临界区查看
        if(money==0)
        {
            money += 200;
            printf("子线程money=%d\n",money);
        }

        //解锁
        pthread_mutex_unlock(&mutex);

        sleep(1);
    }
    return NULL;
}


int main()
{
    pthread_t tid;

    pthread_mutex_init(&mutex,NULL); //初始化互斥量
    pthread_cond_init(&cond,NULL);   //初始化条件变量

    pthread_create(&tid,NULL,pthread_func,NULL);//创建子线程

    money=1000;
    while(1)
    {
        //上锁
        pthread_mutex_lock(&mutex);

        if(money>0)
        {
            money-=100;
            printf("主线程:money=%d\n",money);
        }
        //解锁
        pthread_mutex_unlock(&mutex);

        //如果money=0就通知子线程
        if(money==0)
        {
            printf("通知子线程>:\n");
            pthread_cond_signal(&cond); //唤醒
        }

        sleep(1);
    }

    return 0;
}

结果:
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/prefect_boy/article/details/79945463

深入浅出Linux环境编程(进程基础+IPC+POSIX+线程同步与互斥)

-
  • 1970年01月01日 08:00

Linux程序设计学习笔记----多线程编程之线程同步条件变量

基本概念与原理
  • hu1020935219
  • hu1020935219
  • 2014-08-15 13:40:21
  • 1777

Linux多线程间同步与互斥---条件变量(Conditoin Variable)

Linux多线程间同步与互斥---条件变量(Conditoin Variable)
  • Li_Ning_
  • Li_Ning_
  • 2016-08-22 15:17:13
  • 813

线程同步---条件变量

1. 问题引入:互斥锁问题,假设现在有两个资源A和B,一个线程先拿A再拿B,另一个则相反,这样导致的问题就是死锁,即两个线程无休止的互相等待 #include #include #include ...
  • meetings
  • meetings
  • 2015-08-03 15:58:37
  • 1225

Linux 线程同步---条件变量

1. 相关函数                                                                                             ...
  • hiflower
  • hiflower
  • 2008-03-18 22:17:00
  • 43257

3线程同步-C++11中的条件变量

在C11头文件中包含了如下内容 cv_status 条件等待结果的枚举。 condition_variable 条件变量的主要类,用于实现线程同步。 condition_variable_any 是对...
  • pi314
  • pi314
  • 2016-11-16 17:35:36
  • 375

【Linux开发】linux线程同步方式条件变量介绍及实例

1、利用线程间共享的全局变量进行同步的一种机制。条件变量上的基本操作有:触发条件(当条件变为 true 时);等待条件,挂起线程直到其他线程触发条件。 int pthread_cond_init(...
  • jiayanhui2877
  • jiayanhui2877
  • 2015-05-14 16:36:14
  • 861

线程间使用条件变量同步正确方式

线程间同步标准的使用方式如下: thread 1: pthread_mutex_lock(&mutex); while (!condition) pthread...
  • mumumuwudi
  • mumumuwudi
  • 2015-08-26 08:28:28
  • 1334

java 多线程------条件变量

代码如下--------------- package dxm.com.test; import java.util.concurrent.ExecutorService; im...
  • dingxingmei
  • dingxingmei
  • 2015-08-03 16:26:43
  • 229

linux线程间同步(1)互斥锁与条件变量

线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量以及读写锁。互斥锁(mutex)互斥锁,是一种信号量...
  • callinglove
  • callinglove
  • 2015-06-26 14:45:18
  • 1552
收藏助手
不良信息举报
您举报文章:线程同步--(条件变量)
举报原因:
原因补充:

(最多只允许输入30个字)