A read-write lock that is not real

Source: Internet
Author: User
Tags usleep

There is a single write thread, multiple read thread concurrency scenarios, such as the reading and updating of measurement data, consumers will be more, producers only one. Consider the example:

On the left is a classic solution that locks the entire data operation. For a write data thread, it is obviously a waste to lock all the read threads. A read-write lock (Reader/writer lock) is proposed, even if a read-write lock is used, the essence is the same, and under POSIX pthread its internal implementation is based on mutexes, so it is more expensive. If there is not a heavy read operation to counteract the overhead it introduces, it will cause a decrease in performance. There are several sets of test data to prove this. Myself I did the validation, get the data as follows (a single write thread, 20 read threads), using read-write locks instead of using a mutex is slower. For more information, refer to two links:
* Mutex or Reader Writer Lock
* Multi-threaded programming:efficiency of locking

This kind of problem, in the database domain has a kind of solution, is called Multiversion Concurrency Control, its purpose is to increase the data copy to ensure that the user can use every time the complete data, but not necessarily the newest data. To simplify a little bit, the idea is to create a copy of the data dedicated to writing. When the data is fully ready, switch it out for other threads to read. The original data is converted to the next write use. This is the way that is shown in the right side.
With this scheme, as long as the handling of the writing/reading lock on the can. The performance overhead of this test is because the lock processing time is very short, better than the general mutex and Reader/writer lock (the last algorithm):

The details are not unfolded. There are some more generic ways, called spin Buffer, that interest can be further studied.

The following source code is provided for reference:

#include <pthread.h>#include <iostream>#include <stdio.h>#include <unistd.h>#include <ctime>//#define USE_MUTEX//#define Use_rw_lock//X + Y = 0typedef struct_data{intXintY;} Data;namespace{Data globaldata[2] = {{1,-1}, {1,-1}};intWriteindex =0;intReadingindex =1;floatGlobalreadingtimecost =0.0f;#ifdef Use_mutexpthread_mutex_t mutex = Pthread_mutex_initializer;#endif#ifdef Use_rw_lockpthread_rwlock_t Rwlock;#endif  Const intThread_number = -;}void* Write_thread (void* param) {clock_t begin_time =STD:: Clock (); for(intI=1; i<= +;    i++) {globaldata[writeindex].x = i; GLOBALDATA[WRITEINDEX].Y =-1I Usleep1);#ifdef Use_mutexPthread_mutex_lock (&mutex);#endif#ifdef Use_rw_lockPthread_rwlock_rdlock (&rwlock);#endifReadingindex = Writeindex; Writeindex = (Writeindex +1) %2;#ifdef Use_mutexPthread_mutex_unlock (&mutex);#endif#ifdef Use_rw_lockPthread_rwlock_unlock (&rwlock);#endifUsleep -); }STD::cout<<"[Writing Thread]"<<float(STD:: Clock ()-begin_time)/clocks_per_sec * +<<STD:: Endl;returnNULL;}void* Read_thread (void* param) {clock_t begin_time =STD:: Clock (); for(intI=1; i<=20000; i++) {#ifdef Use_mutexPthread_mutex_lock (&mutex);#endif#ifdef Use_rw_lockPthread_rwlock_wrlock (&rwlock);#endif    intindex = Readingindex;#ifdef Use_mutexPthread_mutex_unlock (&mutex);#endif#ifdef Use_rw_lockPthread_rwlock_unlock (&rwlock);#endif    intx = globaldata[index].x;inty = globaldata[index].y;if(x + Y! =0) {STD::cout<<STD:: Endl <<"wrong data:"<< x <<","<< y <<STD:: Endl; } usleep (3); }STD::cout<<"[Reading Thread]"<<float(STD:: Clock ()-begin_time)/clocks_per_sec * +<<STD:: Endl;returnNULL;}intMainvoid) {intRET =0; pthread_t Id[thread_number];#ifdef Use_rw_lockPthread_rwlock_init (&rwlock, NULL);#endifclock_t Begin_time =STD:: Clock ();//One writing threadret = Pthread_create (&id[0], NULL, write_thread, NULL);if(ret) {STD::cout<<"Failed to launch writing thread."<<STD:: Endl;return-1; }//Four reading threads   for(intI=1; i<thread_number;  i++) {pthread_create (&id[i], NULL, read_thread, NULL); } for(intI=0; i<=thread_number;  i++) {pthread_join (id[i], NULL); }STD::cout<<"Cost:"<<float(STD:: Clock ()-begin_time)/clocks_per_sec * +<<STD:: Endl;return 0;}

Compile the test using the following method:

g++-std=c++11-DUSE_MUTEXthread.-lpthread-othread

Write a document about multi-threading algorithm selection when you are free!

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

A read-write lock that is not real

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.