ミューテックスロックと条件Androidの条件



Mutex Lock Conditions Condition Android



ミューテックス

Mutexは相互に排他的なカテゴリであり、複数のスレッドが同じリソースにアクセスするための時間であり、1つのスレッドのみがこのリソースにアクセスできるようにします

Mutexの宣言と実装



//Mutex.h class Mutex { 48 public: 49 enum { 50 PRIVATE = 0, 51 SHARED = 1 52 } 53 54 Mutex() 55 explicit Mutex(const char* name) 56 explicit Mutex(int type, const char* name = NULL) 57 ~Mutex() 58 59 // lock or unlock the mutex 60 status_t lock() 61 void unlock() 62 63 // lock if possible returns 0 on success, error otherwise 64 status_t tryLock() 65 66 #if defined(__ANDROID__) 67 // Lock the mutex, but don't wait longer than timeoutNs (relative time). 68 // Returns 0 on success, TIMED_OUT for failure due to timeout expiration. 69 // 70 // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep 71 // capabilities consistent across host OSes, this method is only available 72 // when building Android binaries. 73 // 74 // FIXME?: pthread_mutex_timedlock is based on CLOCK_REALTIME, 75 // which is subject to NTP adjustments, and includes time during suspend, 76 // so a timeout may occur even though no processes could run. 77 // Not holding a partial wakelock may lead to a system suspend. 78 status_t timedLock(nsecs_t timeoutNs) 79 #endif 80 81 // Manages the mutex automatically. It'll be locked when Autolock is 82 // constructed and released when Autolock goes out of scope. 83 class Autolock { 84 public: 85 inline explicit Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock() } 86 inline explicit Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock() } 87 inline ~Autolock() { mLock.unlock() } 88 private: 89 Mutex& mLock 90 } 91 92 private: 93 friend class Condition 94 95 // A mutex cannot be copied 96 Mutex(const Mutex&) 97 Mutex& operator = (const Mutex&) 98 99 #if !defined(_WIN32) 100 pthread_mutex_t mMutex 101 #else 102 void _init() 103 void* mState 104 #endif 105 } 106 107 // --------------------------------------------------------------------------- 108 109 #if !defined(_WIN32) 110 111 inline Mutex::Mutex() { 112 pthread_mutex_init(&mMutex, NULL) 113 } 114 inline Mutex::Mutex(__attribute__((unused)) const char* name) { 115 pthread_mutex_init(&mMutex, NULL) 116 } 117 inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { 118 if (type == SHARED) { 119 pthread_mutexattr_t attr 120 pthread_mutexattr_init(&attr) 121 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) 122 pthread_mutex_init(&mMutex, &attr) 123 pthread_mutexattr_destroy(&attr) 124 } else { 125 pthread_mutex_init(&mMutex, NULL) 126 } 127 } 128 inline Mutex::~Mutex() { 129 pthread_mutex_destroy(&mMutex) 130 } 131 inline status_t Mutex::lock() { 132 return -pthread_mutex_lock(&mMutex) 133 } 134 inline void Mutex::unlock() { 135 pthread_mutex_unlock(&mMutex) 136 } 137 inline status_t Mutex::tryLock() { 138 return -pthread_mutex_trylock(&mMutex) 139 } 140 #if defined(__ANDROID__) 141 inline status_t Mutex::timedLock(nsecs_t timeoutNs) { 142 timeoutNs += systemTime(SYSTEM_TIME_REALTIME) 143 const struct timespec ts = { 144 /* .tv_sec = */ static_cast(timeoutNs / 1000000000), 145 /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000), 146 } 147 return -pthread_mutex_timedlock(&mMutex, &ts) 148 } 149 #endif 150 151 #endif // !defined(_WIN32) 152 153 // --------------------------------------------------------------------------- 154 155 /* 156 * Automatic mutex. Declare one of these at the top of a function. 157 * When the function returns, it will go out of scope, and release the 158 * mutex. 159 */ 160 161 typedef Mutex::Autolock AutoMutex 162 163 // --------------------------------------------------------------------------- 164 } // namespace android 165 // --------------------------------------------------------------------------- 166 167 #endif // _LIBS_UTILS_MUTEX_H

ミューテックスで最も重要なことは、ロックおよびロック解除機能です
ロック機能:ロックを呼び出した後、この領域が他の領域よりも先にロックされている場合、ロック機能はこれまでこの領域に入ることができるまで待機します。システムは、1つのスレッドのみが成功をロックできることを保証します。
ロック解除機能:アンロックを呼び出して、ミューテックスミューテックス領域を解放します。このようにして、他のロックは正常に戻ることができます。
trylock関数:領域をロックしようとしているだけなので、ユーザーは、正常にロックされたtrylockが領域に戻ったかどうかを判断する必要があります。

オートロック

AutoLockクラスは、Mutexの内部で定義されたクラスであり、C ++コンストラクタとデストラクタを使用します。AutoLockは、ロックオブジェクトのライフサイクル操作を自動的にロックインおよび解放します。

class Autolock { public: // constructor called when the lock. inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock() } inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock() } // destructor is called when the unlock. inline ~Autolock() { mLock.unlock() } private: Mutex& mLock }

Autolock構成の場合、アクティブな内部メンバー変数mLockはlock()メソッドを呼び出しますが、反対側のデストラクタでは、そのunlock()メソッドを呼び出してロックを解放します。この場合、Autolockオブジェクトがローカル変数である場合、リソースロックのライフサイクルの終わりに自動的に理解します。

状態

主な機能:
wait(Mutex&mutex)スレッドはイベントBとCを待機します
waitRelative(Mutex&mutex、nsecs_t reltime)およびスレッドBの待機タイムアウトC、B、およびCは、待機時間を指定できます。この時間を超えても条件が満たされない場合は、待機を終了します。
トリガー条件による信号()が満たされ、A、B、Cに通知されましたが、1つだけが起動されます。
Broadcast()by覚醒を待っているすべての人に通知するトリガー条件が満たされました。 (放送)

条件はMutexの使用に必要です。これは条件ですが、スレッドオブジェクトに関連付けられた記号でもあります。

class Condition { public: enum { PRIVATE = 0, SHARED = 1 } Condition() Condition(int type)// If the type is SHARED, expressed support for cross-process synchronization conditions ~Condition() status_t wait(Mutex& mutex) status_t waitRelative(Mutex& mutex, nsecs_t reltime) void signal() void broadcast() private: #if defined(HAVE_PTHREADS) pthread_cond_t mCond #else void* mState #endif }

といった:

//android/frameworks/av/services/audioflinger/Threads.h class HenrySenseThread : public Thread { public: MaxxSenseThread(const sp& audioFlinger) void signal() // Thread virtuals bool threadLoop() void exit() private: void activeTracksChanged() status_t getActiveTracksPid(int *pSize, int *pActiveClientPid) sp sMediaPlayerService const sp& getMediaPlayerService() status_t GetActivePidsFromMediaPlayerService(int *size, int *pids) const sp mAudioFlinger Condition mWaitWorkCV Mutex mLock bool mNeedToCheck effect_descriptor_t mDescriptor } #endif

mWaitWorkCVのクラスHenrySenseThreadで宣言された条件変数

//android/frameworks/av/services/audioflinger/Threads.cpp void AudioFlinger::HenrySenseThread::signal() { ALOGV('signal()') mLock.lock() mNeedToCheck = true mWaitWorkCV.signal() // wake-up call in the local wait state mWaitWorkCV.wait (mlock) continues to perform mLock.unlock() } bool AudioFlinger::MaxxSenseThread::threadLoop() { ALOGV('threadLoop()') if (exitPending()) { return false } mLock.lock() if (!mNeedToCheck) { mWaitWorkCV.wait(mLock)// after the current thread in a wait state at mWaitWorkCV, call mWaitWorkCV.signal () wakes up } mNeedToCheck = false mLock.unlock() if (exitPending()) { return false } activeTracksChanged() return true }