Android7.1.2 之 Mutex的实现原理
一、android中互斥的使用:
a、定义mutex类的对象: mutex mlock;
b、在需要进行互斥操作的地方添加automutex _1(mlock);,值得注意的是automutex 是mutex 类的内部类的别名,具体的代码如下:(system\core\include\utils\mutex.h)
typedef mutex::autolock automutex;
注释:c++这种内部类的使用跟java有相同点,也有不同的地方,在文章最后会具体说明。
二、分析mutex的实现原理:
原理:
互斥的使用充分的利用了c++中的构造函数和析构函数,在构造函数中加锁,在析构函数中解锁,只要超出函数的作用域,析构函数就会自动的调用,这样,我们只需要加锁,解锁是自动完成的,避免了死锁等诸多问题。其实mutex类只是对linux线程互斥的再封装,由linux线程互斥对mmutex做具体操作,其中还涉及到原子操作。
代码部分:
mutex的定义部分是内联函数,所以类和定义都在同一个文件(system\core\include\utils\mutex.h),下面是mutex类:
class mutex { ... ... // lock or unlock the mutex status_t lock(); void unlock(); // lock if possible; returns 0 on success, error otherwise status_t trylock(); // manages the mutex automatically. it'll be locked when autolock is // constructed and released when autolock goes out of scope. class autolock { //互斥使用的核心部分 public: inline autolock(mutex& mutex) : mlock(mutex) { mlock.lock(); } inline autolock(mutex* mutex) : mlock(*mutex) { mlock.lock(); } inline ~autolock() { mlock.unlock(); } private: mutex& mlock; }; private: ... ... #if !defined(_win32) pthread_mutex_t mmutex; //互斥的具体操作对象 #else void _init(); void* mstate; #endif };
其他代码部分:
bionic\libc\include\pthread.h : 线程相关的所有接口 bionic\libc\bionic\pthread_mutex.cpp : 线程中关于互斥部分 bionic\libc\include\stdatomic.h : c11标准的原子操作 external\libcxx\include\atomic
c++与java部分的内部类:
c++需要一个显式的成员只想外部类对象,而java内部类对象有一个隐式的成员指向外部类对象。
c++案例:
如metux类中的内部类autolock,在内部类autolock中定义mutex& mlock;就属于显式的成员,只有这样内部类才能操作外部类的所有成员属性和成员方法(包括private成员和静态成员)。
java-成员内部类的案例(网上案例):成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
//外部类 class out { private int age = 12; //内部类 class in { public void print() { system.out.println(age); } } } public class demo { public static void main(string[] args) { out.in in = new out().new in(); in.print(); //或者采用下种方式访问 /* out out = new out(); out.in in = out.new in(); in.print(); */ } }
java-静态内部类的案例:静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法。
public class test { public static void main(string[] args) { outter.inner inner = new outter.inner(); } } class outter { public outter() { } static class inner { public inner() { } } }