Fundamentals of Read and write locks
When a thread already holds a mutex, the mutex blocks all threads attempting to enter the critical section. But consider a situation where the thread holding the mutex is only reading access to the shared resource, while several other threads also want to read the shared resource, but because of the exclusive nature of the mutex, all other threads cannot acquire the lock and cannot read access to the shared resource. However, the fact that multiple threads concurrently read access to shared resources does not cause problems.
In the data read and write operations, more read operations, less write operations, such as database data read and write applications. To satisfy the requirement that currently allows multiple reads, but only one write, the thread provides a read-write lock to be implemented.
Read and write locks are characterized as follows:
1) If there are other threads reading the data, allow other threads to perform read operations, but write operations are not allowed.
2) If there are other threads writing the data, the other threads do not allow read and write operations.
The read-write lock is divided into reading and writing locks, the following rules:
1) If a thread requests a read lock, another thread can request a read lock, but cannot request a write lock.
2) If a thread requests a write lock, the other thread cannot request a read lock, nor can it apply for a write lock.
The data type of a POSIX-defined read-write lock is: pthread_rwlock_t.
basic operation of read-write lock
The following function requires the header file:
#include <pthread.h>
1) Initialize the read/write lock
int Pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
Function:
Used to initialize the read-write lock pointed to by the Rwlock.
Parameters:
rwlock : Pointer to the read-write lock to initialize.
attr : A property pointer to a read-write lock. If attr is NULL, the read-write lock is initialized with the default property, otherwise the read-write lock is initialized with the specified attr.
You can use macros Pthread_rwlock_initializer static Initialize read-write lock, for example:
pthread_rwlock_t my_rwlock = Pthread_rwlock_initializer;
This method is equivalent to using the NULL specified attr parameter to call Pthread_rwlock_init () to complete dynamic initialization, except that the Pthread_rwlock_initializer macro does not check for errors.
return value:
Success: 0, the state of the read-write lock becomes initialized and unlocked.
Failure: not 0 error code.
2) apply for Read lock
int Pthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
Function:
Gets a read lock (read lock) in a blocking manner on the read/write lock. If there is no writer holding the lock, and no writer is blocking it, the calling thread acquires a read lock. If the calling thread does not acquire a read lock, it will block until it acquires the lock. A thread can perform a read lock multiple times on a read-write lock. The thread can successfully call the Pthread_rwlock_rdlock () function n times, but then the thread must call the Pthread_rwlock_unlock () function n times to unlock it.
Parameters:
rwlock: Read-write lock pointer.
return value:
Success: 0
Failure: not 0 error code
int Pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock);
Used to attempt to obtain a read lock on the read-write lock in a non-blocking manner. If any writer holds the lock or has a writer blocking the read-write lock, it immediately fails to return.
3) Apply for write lock
int Pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
Function:
Obtain a write lock (write lock) on the read/write key. If no writer holds the lock, and no writer reader holds the lock, the calling thread acquires a write lock. If the calling thread does not acquire a write lock, it blocks until it acquires the lock.
Parameters:
Rwlock : Read-write lock pointer.
return value:
Success: 0
Failure: not 0 error code
int Pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock);
Used to attempt to obtain a write lock in a read-write lock in a non-blocking manner. If any reader or writer holds the lock, the failure is returned immediately.
4) Unlocking
int Pthread_rwlock_unlock (pthread_rwlock_t *rwlock);
Function:
Either a read lock or a write lock can be unlocked by this function.
Parameters:
Rwlock : Read-write lock pointer.
return value:
Success: 0
Failure: not 0 error code
5) Destroy read/write lock
int Pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
Function:
Used to destroy a read-write lock and release all associated resources (so-called all refer to resources that are automatically requested by Pthread_rwlock_init ()).
Parameters:
rwlock: Read-write lock pointer.
return value:
Success: 0
Failure: not 0 error code
read-write lock application Example
The following is an instance where a read-write lock is used to implement 4 threads reading and writing a piece of data. In this sample program, a total of 4 threads were created, of which two threads were used to write data, and two threads were used to read the data. When a thread reads, other threads allow read operations, but write operations are not allowed, and when a thread writes, no other threads allow read or write operations.
The sample code is as follows:
#include <stdio.h> #include <unistd.h> #include <pthread.h>pthread_rwlock_t rwlock; Read-write lock int num = 1;//read operation, other threads allow read operations, but do not allow write operations void *fun1 (void *arg) {while (1) {Pthread_rwlock_rdlock (&rwlock);p rintf (" Read num first===%d\n ", num);p thread_rwlock_unlock (&rwlock); sleep (1);}} Read operations, other threads allow read operations, but do not allow write operations void *fun2 (void *arg) {while (1) {Pthread_rwlock_rdlock (&rwlock);p rintf ("Read num second== =%d\n ", num);p thread_rwlock_unlock (&rwlock); sleep (2);}} Write operation, no other threads are allowed to read or write operation void *fun3 (void *arg) {while (1) {pthread_rwlock_wrlock (&rwlock); num++;p rintf ("Write Thread first\n ");p Thread_rwlock_unlock (&rwlock); sleep (2);}} Write operation, no other threads are allowed to read or write operation void *fun4 (void *arg) {while (1) {pthread_rwlock_wrlock (&rwlock); num++;p rintf ("Write Thread second\n ");p Thread_rwlock_unlock (&rwlock); sleep (1);}} int main () {pthread_t ptd1, PTD2, Ptd3, Ptd4;pthread_rwlock_init (&rwlock, NULL);//Initialize a read/write lock//create thread pthread_create ( &PTD1, NULL, FUN1, NULL);p thread_create (&PTD2, NULL, FUN2, NULL);p thread_create (&p td3, NULL, FUN3, NULL);p thread_create (&PTD4, NULL, FUN4, NULL),//wait for thread to end, reclaim its resources pthread_join (ptd1,null);p Thread_ Join (Ptd2,null);p thread_join (ptd3,null);p Thread_rwlock_destroy (&rwlock);//Destroy read-write lock return 0;}
The results of the operation are as follows:
For this tutorial sample code download please click here.
Reference: Linux Advanced Programming
Linux system Programming-thread synchronization and mutual exclusion: read-write locks