Analysis of inter-thread communication two: read-write lock and Spin lock

Source: Internet
Author: User
Tags mutex

The above discusses the mutex and conditional variables used for thread synchronization, this article will discuss the use of read and write locks and spin locks , and give the corresponding code and considerations, the relevant code can also be downloaded on my GitHub .

read/write lock

The mutex is either locked or unlocked, and only one thread can lock it at a time, while a read-write lock distinguishes between a thread's reading data lock request and a write data lock request, which in some cases has higher concurrency. For read-write locks, only one thread at a time can occupy write-mode read-write locks, but multiple threads can occupy read-mode reading and writing locks at the same time. While read-write locks are implemented differently, read-write locks usually block subsequent read-mode requests if another thread attempts to lock in write mode when a write-lock is locked in reading mode. This avoids the long-term use of read-mode locks and waits for write-mode lock requests to remain unmet. Read-write locks are also called shared - exclusive Locks (shared-exclusive). The following is a read-write lock to solve the classic reader and writer problems, the code is as follows:

#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #define Maxnthreads 100#define MIN (A) ((a) < (b))? A):(B)) void *reader (void *); void *writer (void *);  int nloop = Nreaders = 6, Nwriters = 4;struct {pthread_rwlock_t rwlock;  pthread_mutex_t Rcountlock;  int nreaders; int nwriters;}    Shared = {Pthread_rwlock_initializer, pthread_mutex_initializer};int main (int argc, char **argv) {int C, I;    pthread_t Tid_readers[maxnthreads], tid_writers[maxnthreads];            while ((c = getopt (argc, argv, "n:r:w:"))! =-1) {switch (c) {case ' n ': Nloop = atoi (Optarg);        Break            Case ' r ': nreaders = MIN (Atoi (Optarg), maxnthreads);        Break            Case ' W ': Nwriters = MIN (Atoi (Optarg), maxnthreads);        Break }} if (Optind! = argc) {printf ("usage:read_write_lock_example [-N #loops] [-R #reAders] [-W #writers] ");    return 1; }/* Create all the reader and writer threads */for (i = 0; i < nreaders; i++) pthread_create (&tid    _readers[i], NULL, reader, NULL);    for (i = 0; i < nwriters; i++) pthread_create (&tid_writers[i], NULL, writer, null);     /* Wait for all the threads to complete */for (i = 0; i < nreaders; i++) Pthread_join (Tid_readers[i], NULL);    for (i = 0; i < nwriters; i++) Pthread_join (Tid_writers[i], NULL); Exit (0);}    void* reader (void *arg) {int i;        for (i = 0; i < Nloop; i++) {pthread_rwlock_rdlock (&shared.rwlock);        Pthread_mutex_lock (&shared.rcountlock);  shared.nreaders++; /* shared by all readers;        Must protect */Pthread_mutex_unlock (&shared.rcountlock);            if (Shared.nwriters > 0) {printf ("Reader:%d writers found", shared.nwriters);        Return (void*) 0; } pthread_mutex_lock (&sharEd.rcountlock);  shared.nreaders--; /* shared by all readers;        Must protect */Pthread_mutex_unlock (&shared.rcountlock);    Pthread_rwlock_unlock (&shared.rwlock); } return (NULL);}    void* writer (void *arg) {int i;        for (i = 0; i < Nloop; i++) {pthread_rwlock_wrlock (&shared.rwlock);  shared.nwriters++; /* Only one writer; Need not protect */if (Shared.nwriters > 1) {printf ("Writer:%d writers found", Shared.nwrit            ERS);        Return (void*) 0;            } if (Shared.nreaders > 0) {printf ("Writer:%d readers found", shared.nreaders);        Return (void*) 0;  } shared.nwriters--; /* Only one writer;    Need not protect */Pthread_rwlock_unlock (&shared.rwlock); } return (NULL);}

The above program implementation is read-in thread and write thread synchronization, there are several places worth noting:

I) in reader , when modifying the shared.nreaders value (although the previous use of Pthread_rwlock_rdlock with A read lock), the mutex needs to be locked because multiple threads can get read locks and modify this value.

II) in writer , when modifying the shared.nwriters value, it is not necessary to use a mutex lock protection, because only one thread can get a write lock.

spin lock (spin locks)

 A spin lock is similar to a mutex, and when the lock thread that gets the mutex is blocked, the thread goes to sleep, and when the spin lock is acquired, the thread is busy waiting (busy-waiting) state, that is, does not yieldCPU, ConsumptionCPUResources, try again and again to get a spin lock until you get it. Spin locks are suitable for situations where a thread holds a spin lock for a shorter time and the thread does not want to consume the rescheduling cost. Spin locks are typically usedTest-and-setinstruction is implemented efficiently.

Spin locks can be obtained using pthread_spin_lock or phread_spin_trylock , but it is important to note that during the spin lock, the thread Do not call any functions that might put the thread to sleep, because if you do this, other threads will consume CPU resources when they attempt to acquire the spin lock .

Many mutex implementations are very efficient, and even in the case of spin locks, the program performance is almost unaffected by the use of mutexes. In fact, some mutex in the acquisition of locks, if the current lock is not available, the thread does not sleep immediately, but busy waiting for a period of time to see if it can be obtained (and the spin lock is busy, etc.), if more than a certain amount of time, the thread will go to sleep state. In addition, the current context of the processor switching thread is getting faster and slower, making it more and more possible to use spin locks. Whether to use mutex or spin lock, someone

a mutex spin lock It costs more (mostly context switching), but it can be adapted to complex scenarios in real-world development, providing greater flexibility in the premise of guaranteed performance.

b, spin lock lock/unlock better performance ( directive ) spin lock Not a good idea ( Typically, a multi-threaded program operates on a lock for thousands of times if a failed lock operation (contended lock requests) Too much will waste a lot of time waiting for the empty wait

C.the more insured approach may be to use the Mutex first (conservatively) , and then, if there is further demand for performance, try to tune with spin lock . After all, our program is not as high-performance as Linux kernel (the most common lock operation for Linux kernel is spin lock and RW lock).

Resources

Advanced Programming for the UNIX environment 11.6 thread synchronization
"UNIX Network Programming Volume 2: interprocess communication" Chapters 7th, 8th and 10th
http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/



Analysis of inter-thread communication two: read-write lock and Spin lock

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.