The usage of Mutex and Condition of thread synchronization in Android

Haili Tian
2013-08-10

The synchronization classes packaged by Android mainly include MUTEX (AutoMutex) and Condition. This article analyzes how to use them. For specific implementations, see " The Implementation of MUTEX and Condition of Thread Synchronization in Android " and " Usage of MUTEX and Condition of pthread ".
Keywords: Mutex, Condition Variable, AutoLock/AutoMutex, Android Keywords: Mutex, Condition Variable
, Auto Lock/Auto Mutex, Android

One, MUTEX


Look at the external interface definition of MUTEX (declared in frameworks/native/include/utils/Mutex.h)
<Figure 1 TODO>

1.1 Construction/Destruction

Mutex();
Mutex(const char* name);
Mutex(int type, const char* name = NULL);
~Mutex();

The difference in the constructor is the parameters:
-name is to specify the name for MUTEX, if not specified, the default is NULL;
-type is to specify the type of MUTEX, there is
    enum {
        PRIVATE = 0,
        SHARED = 1
    };
Two types: PRIVATE is used within the process; SHARED is suitable for cross-process sharing.
If not specified, the default type is PRIVATE.

1.2 Function function

MUTEX has the following three main functions:
    status_t    lock();
    void        unlock();
    status_t    tryLock();

lock() Acquire the lock. If it is acquired, it will return, otherwise it will be suspended;
unlock() will release the lock;
tryLock() will lock if the current lock can be acquired (not acquired by other threads), otherwise it will return directly. Return value: 0 means success; other values ​​fail. The difference with lock() is that it returns in time regardless of success or failure, instead of suspending and waiting.

The thread acquires the lock through lock() before entering the critical area protected by MUTEX. After acquiring the lock, the code in the critical area can be executed, and the lock is released by unlock after exiting the critical area.
At most one thread is executing in the critical area at a certain moment. If thread T1 is already executing, other threads T2 that want to enter the critical area will be suspended and waiting after executing lock(); until thread T1 releases the lock, Thread T2 can obtain the lock and enter the critical section for execution.

lock()/unlock() must be used together, tryLock() is to choose whether to unlock() according to whether the lock is obtained according to the result of the execution.

1.3 Typical scenario

m_mutex.lock();
// CRITICAL AREA,需要保护的内容
m_mutex.unlock();

Two, Condition

Look at the external interface definition of Condition (declared in frameworks/native/include/utils/Condition.h)
<Figure 2 TODO>

2.1 Construction/Destruction

    Condition();
    Condition(int type);
    ~Condition();

The difference between the constructor is the type parameter:
-type is the type of the specified Condition, there are
    enum {
        PRIVATE = 0,
        SHARED = 1
    };
Two types: PRIVATE is used within the process; SHARED is suitable for cross-process sharing.
If not specified, the default type is PRIVATE.

2.2 Function function

Condition has the following four main functions:
    status_t wait(Mutex& mutex);
    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
    void signal();
    void broadcast();

wait() Wait for the condition variable (Condition Variable)
    Mutex as a parameter. The MUTEX must be locked before calling this function.
    Executing this function will unlock the MUTEX and wait for the condition variable. If the condition variable cannot be obtained, it is suspended and waiting; if the condition variable is obtained, MUTEX is relocked and returned. These operations are all atomic operations.
    After the function is executed, Mutex is relocked, so after the function is executed, there must be an unlock operation of Mutex.
The difference between waitRelative() and wait() is that there will be a wait timeout period, and the condition variable will be returned if the time is reached. The result can be judged by the return value.
signal() and broadcast() trigger condition variables (Condition Variable)
    The difference between signal() and broadcast() is that signal() only allows one thread waiting for the condition variable to obtain; broadcast() allows all threads waiting for the condition variable Obtain and continue to execute.
    Mutex must also be locked before signal() and broadcast() are executed, and Mutex must be unlocked after execution.

2.3 Typical scenario

Execution of thread T1:
m_mutex.lock();   
m_cond.wait(m_mutex);   
m_mutex.unlock();
Thread T1 is waiting for the satisfaction of a certain condition through the condition variable.

Thread T2 executes:
m_mutex.lock();   
m_cond.signal();   
m_mutex.unlock();
After the thread T2 satisfies the condition, it notifies that the condition is satisfied through the condition variable.

三、Autolock/AutoMutex

Autolock is defined to simplify the use of Mutex. It is also defined in frameworks/native/include/utils/Mutex.h, which encapsulates Mutex and uses the construction and destruction mechanism of c++.
        Autolock(Mutex& mutex);
        Autolock(Mutex* mutex);
        ~Autolock();

The usage is very simple. Define a local temporary AutoMutex variable. In the place where the variable is defined, the constructor is automatically called, and the lock() operation of Mutex will be executed; at the end of the variable scope, the destructor will be automatically called , Will perform the unlock operation of Mutex.
Therefore, you can define an AutoMutex variable at the beginning of the area that needs Mutex protection, and you can use Mutex to protect the area.

Four, summary

This article briefly introduces the use of Mutex (AutoMutex) and Condition commonly used synchronization mechanisms in Android. Follow-up articles (" The Implementation of MUTEX and Condition of Thread Synchronization in Android " and " Usage of MUTEX and Condition of pthread ") see how they are implemented.


Guess you like

Origin blog.csdn.net/thl789/article/details/9879151