<linux线程>同步互斥机制之【条件变量】

来源:互联网 发布:淘宝店铺怎么投诉 编辑:程序博客网 时间:2024/05/17 05:04

一、概念理解

1、条件变量是逻辑稍复杂一点的同步互斥机制,它必须与互斥锁一起使用。

2、条件变量用于线程间,等待某一条件发生(和信号类似),它可以将线程从某种睡眠等待中唤醒。

3、条件变量利用线程间共享的资源(一般是全局变量)进行同步的一种机制。

总体来说:条件变量就是利用线程间共享资源的状态变化的通信。当一个线程的某个行为需要对共享资源的状态改变才能执行,这时就用条件变量。

二、逻辑理解

我们以打钱取钱的例子来看它的逻辑:



三、条件变量使用步骤

(1)定义条件变量和互斥锁。

(2)初始化互斥锁和条件变量。

(3)使条件成立的线程

①加锁。

②访问数据,使条件成立。

③通知唤醒其它线程。

④解锁。

(4)条件变量等待线程

①解锁。

②判断条件是否成立:

A 成立:访问数据--->解锁退出。

B 不成立:休眠等待被唤醒。

(5)若线程被唤醒,则重新回到(4)。

(6)销毁互斥锁和条件变量。

四、条件变量相关API(函数)

1、定义: pthread_cond_t 类型

2、初始化: int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr *restrict attr); ——第二个参数一般设为NULL。

3、休眠等待: int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);——另外,有pthread_cond_timewait(pthread_cond_t *restrict cond, pthread_mutex_t * mutex, const struct timespec *restrict abstime);函数可以设置超时时间。

4、唤醒条件变量等待线程: int pthread_cond_broadcast(pthread_cond_t *cond); 

int pthread_cond_signal(pthread_cond_t *cond);——前者唤醒所有线程,后者用于唤醒一个休眠等待中的线程 。

5、销毁条件变量: intpthread_cond_destory(pthread_cond_t *cond);

五、C代码描述

#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <pthread.h>//共享资源int money = 156;//定义互斥锁和条件变量pthread_mutex_t m;pthread_cond_t v;void *routine(void *args){printf("===孩子[%d]没钱花了===\n", (int)args);pthread_mutex_lock(&m);while(money < 100){//pthread_cond_timedwait(&v, &m);pthread_cond_wait(&v, &m);}fprintf(stderr, "我是第%d个孩子,当前有: money = %d,我取了100,剩下%d\n", (int)args, money, money-100);money -= 100;pthread_mutex_unlock(&m);pthread_exit(NULL);}int main(int argc, char *argv[]){int n;//传入孩子个数,等会儿需要创建对应个数的线程if(argc != 2){printf("格式: %s <孩子个数>\n", argv[0]);return 1;}//初始化互斥锁和条件变量pthread_mutex_init(&m, NULL);pthread_cond_init(&v, NULL);//获取孩子个数,需要创建的线程个数int thread_nums = atoi(argv[1]);printf("总共有%d个孩子\n", thread_nums);//创建对应孩子个数的线程pthread_t tid[thread_nums];int i;for(i=0; i<thread_nums; i++){pthread_create(&tid[i], NULL, routine, (void *)i);//传入是第几个孩子i}sleep(5);//上锁pthread_mutex_lock(&m);//修改资源,改变条件printf("我是父母,请输入准备存入多少钱:");scanf("%d", &n);money += n;//群发通知所有线程pthread_cond_broadcast(&v);//解锁pthread_mutex_unlock(&m);//回收所有线程, 阻塞等待线程结束for(i=0; i<thread_nums; i++){pthread_join(tid[i], NULL);}//销毁互斥锁和条件变量pthread_mutex_destroy(&m);pthread_cond_destroy(&v);return 0;}



原创粉丝点击