博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android中线程同步之Mutex与Condtion的用法
阅读量:4155 次
发布时间:2019-05-25

本文共 2566 字,大约阅读时间需要 8 分钟。

Android封装的同步类主要有MUTEX(AutoMutex)与Condition。本文分析如何使用他们,具体的实现参见《
》与《
》。

Keywords: Mutex, Condition Variable, AutoLock/AutoMutex, Android

关键字:互斥体、条件变量、自动锁/自动互斥体、Android


一、MUTEX


看MUTEX的外部接口定义(声明在frameworks/native/include/utils/Mutex.h中)

<图1 TODO>


1.1 构造/析构

[cpp]   
  1. Mutex();  
  2. Mutex(const char* name);  
  3. Mutex(int type, const char* name = NULL);  
  4. ~Mutex();  

构造函数的区别在于参数:

- name 是为MUTEX指定名字,如不指定,缺省是NULL;

- type 是指定MUTEX的类型,有

[cpp]   
  1. enum {  
  2.     PRIVATE = 0,  
  3.     SHARED = 1  
  4. };  
两种类型:PRIVATE是进程内部使用的;SHARED是适用于跨进程共享的。

如不指定,缺省是PRIVATE的类型。


1.2 功能函数

MUTEX有下面三个主要的功能函数:

[cpp]   
  1. status_t    lock();  
  2. void        unlock();  
  3. status_t    tryLock();  

lock()    获取锁。如果获取就返回,否则挂起等待;

unlock()  释放锁;

tryLock() 如果当前锁可被获取(未被别的线程获取)就lock,否则也直接返回。返回值:0代表成功;其它值失败。与lock()的区别在于不论成功与否都会及时返回,而不是挂起等待。


线程在进入MUTEX保护的临界区之前通过lock()获取锁,获取锁之后可以执行临界区内的代码,退出临界区之后通过unlock释放锁。

某一时刻临界区内至多只有一个线程在执行,如果已有线程T1在执行,要进入临界区的其它线程T2在执行lock()之后就会被挂起等待;直到线程T1释放掉锁之后,线程T2才能获得锁进入临界区执行。


lock()/unlock()必须配合使用,tryLock()则要根据执行的结果有无获得锁而选择是否unlock()。


1.3 典型场景

[cpp]   
  1. m_mutex.lock();  
  2. // CRITICAL AREA,需要保护的内容  
  3. m_mutex.unlock();  

二、Condition

看Condition的外部接口定义(声明在frameworks/native/include/utils/Condition.h中)

<图2 TODO>


2.1 构造/析构

[cpp]   
  1. Condition();  
  2. Condition(int type);  
  3. ~Condition();  

构造函数的区别在于type参数:

- type 是指定Condition的类型,有

[cpp]   
  1. enum {  
  2.     PRIVATE = 0,  
  3.     SHARED = 1  
  4. };  
两种类型:PRIVATE是进程内部使用的;SHARED是适用于跨进程共享的。

如不指定,缺省是PRIVATE的类型。


2.2 功能函数

Condition有下面四个主要的功能函数:

[cpp]   
  1. status_t wait(Mutex& mutex);  
  2. status_t waitRelative(Mutex& mutex, nsecs_t reltime);  
  3. void signal();  
  4. void broadcast();  

wait() 等待条件变量(Condition Variable)

    Mutex作为参数,调用该函数之前该MUTEX必须已经被lock住。

    执行该函数,会unlock该MUTEX,并等待条件变量。如果不能获得该条件变量,就被挂起等待;获得了该条件变量,就重新lock住MUTEX并返回。而这些操作都是原子操作的。

    该函数执行之后,Mutex被重新lock住,所以执行函数之后,必须有Mutex的unlock操作。

waitRelative()与和wait()的区别是,会有一个等待超时时间,到了时间没有获得该条件变量也会返回,可通过返回值判断结果。

signal()和broadcast() 触发条件变量(Condition Variable)

    signal()和broadcast() 的区别是,signal()只允许等待该条件变量的一个线程获得;broadcast()允许等待该条件变量的所有线程获得并继续执行。

    signal()和broadcast() 执行之前也必须lock住Mutex,执行之后unlock Mutex。


2.3 典型场景

线程T1的执行:

[cpp]   
  1. m_mutex.lock();     
  2. m_cond.wait(m_mutex);     
  3. m_mutex.unlock();  
线程T1通过条件变量在等待某个条件的满足。


线程T2执行:

[cpp]   
  1. m_mutex.lock();     
  2. m_cond.signal();     
  3. m_mutex.unlock();  
线程T2在满足条件之后,通过条件变量通知条件满足。


三、Autolock/AutoMutex

Autolock是为了简化Mutex的使用而定义的,它也定义在frameworks/native/include/utils/Mutex.h中,封装了Mutex,并利用c++的构造与析构机制。

[cpp]   
  1. Autolock(Mutex& mutex);  
  2. Autolock(Mutex* mutex);  
  3. ~Autolock();  

用法很简单,定义一个局部临时的AutoMutex变量,在该变量定义的地方,构造函数被自动调用,会执行Mutex的lock()操作;在该变量作用域结束的地方,析构函数会被自动调用,会执行Mutex的unlock操作。

所以,可以在需要Mutex保护的区域开始的地方定义一个AutoMutex变量即可,即可实现用Mutex对该区域的保护。


四、总结

本文简要介绍了Android中常用的同步机制Mutex(AutoMutex)、Condition的使用。后续文章(《
》与《
》)看它们是如何实现的。

转载地址:http://nswxi.baihongyu.com/

你可能感兴趣的文章
我在网易做了6年前端,想给求职者4条建议
查看>>
SQL1015N The database is in an inconsistent state. SQLSTATE=55025
查看>>
RQP-DEF-0177
查看>>
MySQL字段类型的选择与MySQL的查询效率
查看>>
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>
SVN-无法查看log,提示Want to go offline,时间显示1970问题,error主要是 url中 有一层的中文进行了2次encode
查看>>
NGINX
查看>>
Qt文件夹选择对话框
查看>>
DeepLearning tutorial(7)深度学习框架Keras的使用-进阶
查看>>
第三方SDK:JPush SDK Eclipse
查看>>
第三方开源库:imageLoader的使用
查看>>
Android studio_迁移Eclipse项目到Android studio
查看>>
转载知乎-前端汇总资源
查看>>