关于mutex与cond的用法
来源:互联网 发布:ecshop分销系统源码 编辑:程序博客网 时间:2024/05/21 06:31
锁的概念:在CPU运行过程中,不会单一的取执行一个事件,而是通过线程,或者进程来进行执行,这样CPU的利用率才得以提高,但是在不同的线程之间,由于互相独立,那么对于资源的访问来说,就可能同时进行,假如A进程获取一个临时变量temp的值,但是在获取的同时,B进程却将temp的值改变了,这时就会出现资源访问的冲突,为了更好的解决这个问题,就有了锁的概念,说的明白些,他就像现实中的锁一样,我们程序中所有的资源,包括变量,内存等都存放在一个房子里,开始时,锁处于开锁状态,如果某一个线程需要访问资源时,就需要拿到这把锁,进到房子里,把门锁上,这样就不会有其他人来干扰你,等你对资源访问结束后,在把锁打开,放下锁,这样别人就可以进入,这样就保证了对资源访问的顺序,这种锁叫互斥锁,这种机制是我们所说的避免竞争。
条件变量:条件变量是线程同步的一种机制。它给多个线程提供一个回合场所。所谓的条件变量就是需要满足这个条件,才可以继续进行操作。
互斥锁:
1.初始化:
1)动态方式
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
mutex 出参,互斥锁
attr 互斥锁的属性,NULL表示默认/缺省的属性
2)静态的方式
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //一般都选择静态方式
2.加锁:
int pthread_mutex_lock(pthread_mutex_t *mutex);
给mutex互斥锁加锁
1.互斥锁没有被锁:加锁
2.互斥锁已经被锁:阻塞/等待,直到被解锁,然后再对mutex互斥锁加锁
3.解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
条件变量:
1.初始化:
动态方式:
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
静态的方式:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2.等待条件变量
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
原子性的解锁并阻塞/等待条件变量。
3.唤醒条件变量
int pthread_cond_signal(pthread_cond_t *cond);
上面的是函数的介绍,为了方便查看,接下来说一下为什么cond和mutex要配合使用。
首先:在pthread_cond_wait()函数之前,要人为获取一把锁,在pthread_cond_wait()执行时,会自动释放这个锁,并且处于等待/阻塞条件,等待信号来临,一但信号来临,那么在pthread_cond_wait()函数调用返回之前,自动将指定的互斥量重新锁住,所以必须在pthread_cond_wait()之后再人为释放锁。其结实际用法为下:
pthread_mutex_lock(&mutex); //加锁
pthread_cond_wait(&flag,&mutex); //等待,清除标记flag
pthread_mutex_unlock(&mutex); //解锁
其次:对于pthread_cond_signal()函数有两种用法,第一种在加锁与解锁之间,第二种是在加锁解锁之后:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&flag);
pthread_mutex_unlock(&mutex);
这种方式的缺点是:在某线程中,会遭虫等待线程从内核中唤醒(cond_signal是有内核发起的),然后又回到内核空间(cond_wait返回后会有原子加锁的行为),所以这一来一回会产生性能的问题,但是在Linux下或者NPTL里面不会,因为Linux线程中有两个队列即cond_wait和cond_signal两个队列,pthread_cond_signal()只是让线程在从wait队列移动到cond队列,不会再永和空间和内核之间往返,不会有应能损耗。
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&flag);
这种方式的缺点是:如果在unlock和signal之前有一个优先级更低的线程正在等待mutex的话,那么他就会抢占高优先级的线程,而上面的情况则不会出现。
优点是:不会产生性能的损耗,因为在signal之前就已经解锁了。
cond和mutex两个组合使用是为了避免,在一个线程中,如果在wait之前,另一个函数已经完成signal了,那么这个线程将阻塞在这里,从而错过了signal,所以用mutex来实现两个进程的同步,当我等待前上锁,等待后释放锁,然后另一个线程获取锁,产生signal信号,在释放锁。
下面给出一个小程序来测试一下:
#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <ctype.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //静态,解锁状态pthread_cond_t flag = PTHREAD_COND_INITIALIZER; //静态,置位状态int main(int argc ,char *argv[]){ pthread_t t1; void *numWords(void *); pthread_create(&t1,NULL,numWords,NULL); pthread_mutex_lock(&mutex); //加锁 pthread_cond_wait(&flag,&mutex); //等待,清除标记flag printf("pth 1\n"); pthread_mutex_unlock(&mutex); //解锁 return 0;}void *numWords(void *f){ pthread_mutex_lock(&mutex); printf("pth 2\n"); pthread_mutex_unlock(&mutex); pthread_cond_signal(&flag); return NULL;}在程序运行后,打印结果,pth 2 永远在pth 1之前。即两个新城通过mutex与cond的结合使其线程间同步。
如果去掉mutex
#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <ctype.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //解锁状态pthread_cond_t flag = PTHREAD_COND_INITIALIZER; //置位状态int main(int argc ,char *argv[]){ pthread_t t1; void *numWords(void *); pthread_create(&t1,NULL,numWords,NULL); pthread_cond_wait(&flag,&mutex); //等待,清除标记flag printf("pth 1\n"); return 0;}void *numWords(void *f){ printf("pth 2\n") pthread_cond_signal(&flag); return NULL;}程序在运行时,会出现阻塞情况,分线程先执行了signal即打印显示pth 2,然后程序阻塞,无法显示 pth 1,这就是为什么cond与mutex要结合使用的原因。
- 关于mutex与cond的用法
- tf.cond()的用法
- mutex, cond; 竞争, 同步问题
- synchronized/wait/notify 与 mutex/cond wait wake ~ 链表队列 生产消费问题
- mutex和cond为何需要配合使用
- 浅谈pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex)
- linux 多线程 pthread_cond_wait(&cond,&mutex)理解
- pthread 条件变量(cond),sem,mutex
- c posix thread mutex cond rwlock
- std::mutex的用法
- Android中线程同步之Mutex与Condtion的用法
- Android中线程同步之Mutex与Condtion的用法
- Android中线程同步之Mutex与Condtion的用法
- Android中线程同步之Mutex与Condtion的用法
- 关于网上的一段monitor与mutex的例子。
- tf.cond 与 tf.control_dependencies 的控制问题
- pthead cond的理解
- mutex和condition的用法
- Linux下Find文件查找与Grep文件内容查找命令
- python的List
- 深入浅出vector之resize()/reserve(), size()/capacity()
- 元类及创建元类的方法(面试用
- 使用PIL生成用户头像缩略图
- 关于mutex与cond的用法
- springcloud(二):注册中心Eureka
- 用filter过滤器实现login入口
- Android平台使用openGL ES 2.0实现预览摄像头数据功能
- 推荐!国外程序员整理的机器学习资源大全
- The folder is already a source folder
- POJ 1177 线段树+扫描线
- leetcode--Sort Colors
- FreeCodeCamp高级算法Advance Algorithm Scripting