Read-Write Lock pthread_rwlock

1. What is the read-write lock

   In many cases, there is access to shared variables of the following characteristics: In most cases the thread just read the value of the shared variable is not modified, only a very few cases,

Thread will truly change the value of the shared variable. In this case, the request is no need to read between synchronized, concurrent access between them is safe. but

You must be mutually exclusive write requests and read other requests.
  This situation exists in practice, such as configuration items. Most of the time, the configuration change is not going to happen, the situation occasionally modify the configuration will appear. in case

Use mutex, completely prevented concurrent read request, will result in loss of performance. In this consideration, POSIX introduced read-write lock.

 

II. Lock write API

  1. The write lock attributes

    Write lock attributes (pthread_rwlockattr_t) has two: lockkind and pshared.

    (. 1) lockkind : read and write strategies, including read priority (default property), write priority.

    Read priority : If subsequent requests come in the write lock to read lock request is not a write lock request is blocked. If the read lock requests fought the arrival of a steady stream, as long as there

        Did not complete a read lock, write lock no points. This policy will lead to the earlier write lock starvation .

    Write priority : Once a thread application write lock, write lock request back soon read lock requests will all be blocked, before the write request can not get a lock.

enum 
{ 
PTHREAD_RWLOCK_PREFER_READER_NP, // readers priority (default property) 
PTHREAD_RWLOCK_PREFER_WRITER_NP, // readers priority 
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, // write preferred 
PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP // readers priority 
};
/ * Get and set properties * /
int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t * attr, int * pref);
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t * attr, int * pref);

 

     (2)pshared 

    PTHREAD_PROCESS_PRIVATE: read-write lock in the competition process - default properties

    PTHREAD_PROCESS_PUBLIC: competition between reading and writing process lock 

// Set the attribute pshared 
int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared); 
// Get property pshared 
int pthread_rwlockattr_getpshared (pthread_rwlockattr_t * attr, int * pshared);

 

  1. Create

int pthread_rwlock_init(pthread_rwlock_t *rwlock,  const pthread_rwlockattr_t *attr);

pthread_rwlock_t  rwlock = PTHREAD_RWLOCK_INITIALIZER

  2. Obtain

int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr)  //读锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr)  //写锁

  3. Release

int pthread_rwlock_unlock (pthread_rwlock_t * rwptr) // read or write locks unlock

  4. Destruction

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

 

III. The principle read-write lock

variable  Explanation
__lock Management read-write lock locks the global competition, whether it is read or write lock to unlock the lock, will be mutually exclusive
__writer Write lock holder thread ID, if 0 indicates that the current wireless Cheng holds a write lock
__nr_reads The number of read locks held by threads
__nr_reads_queued The number of parties waiting threads read lock
__nr_writers_queued The number of queued write lock thread

  Whether the application is to apply a read lock or write lock or unlock, do have at least one global mutex (corresponding to __lock) of the locking and unlocking, without considering blocking, just consider

Overhead operation itself, the overhead of locking and unlocking read-write lock is twice the mutex. Of course, before the end of the function or prior to entering the obstruction, it will be a global mutex release.

1. For a read lock request, if:

    (the I) wireless Cheng holds a write lock, namely == 0 __writer

    (II) is used in the reader-first strategy or no write lock waiters (__nr_writers_queued == 0)

  when when two conditions are met, read lock request read locks are available immediately, before returning to perform __nr_readers ++, represents an increase of a thread owns a read lock.

  Is not satisfied, then the execution __nr_readers_queued ++, represents an increase of a read lock waiters, then call futex, into obstruction. When I woke up, it performs

__nr_readers_queued-, and then determines again whether satisfy conditions 1 and 2

2. For a write lock request, if:

    (the I) the radio path has the write lock, i.e. == 0 __writer

    (II) does not hold the lock thread, That __nr_readers == 0

  as long as the above conditions are met, it will immediately get a write lock, the __writer set ID thread (scheduling domain)

  If not, then execution __nr_writers_queued ++, it represents an increase a write lock waiters thread, then execution mutex into a wait. Wake up, perform

__nr_writers_queued-, then re-judgment conditions 1 and 2.

3. For unlocking, if the current lock is a write lock, then do the following:

    performing __writer = 0, represents a write lock release

    according __nr_writers_queued decided whether or not the write lock waiters, if there is a write lock waiters wake-up

 if no write lock waiters, it is determined that there is no read lock waiters; if so, it will wake up together all read lock waiters.

 If the current lock is a read lock, then do the following:

    execution __nr_readers-, indicating a read lock occupants less a

    judge __nr_readers is equal to 0, then it is said he was the last occupant of a read lock, write lock waiting need to wake up or who read lock waiters:

    according __nr_writers_queued determine whether there is a write lock waiters, and if so, wake up a thread waiting write lock
    if no write lock waiters to determine whether there is a read lock waiters, and if so, wake up all the read lock waiters

Guess you like

Origin www.cnblogs.com/blackandwhite/p/12447522.html