Use shared_ptr to implement copy-on-write

Source: Internet
Author: User
Use shared_ptr to implement copy-on-write

Scenario:
A multi-threaded C ++ program that runs 24 h x 5.5d. There are several working threads threadw {0, 1, 2, 3} to process the transaction requests sent by the customer. There is also a background thread threadb, which occasionally updates reference data in the program. These threads all deal with a hash table. The working thread is read-only and the background thread reads and writes data. Some synchronization mechanisms must be used to prevent data corruption. The sample code here replaces the hash table with STD: map, which means the same:

Typedef Map <string, vector <pair <string, int> map;

The key of map is the user name, value is a vector, and the minimum transaction interval of different stock is stored in it. The vector has sorted the order and can be searched by binary.

Our system requires that the latency of the working thread be as small as possible, and the background thread latency can be slightly larger. Within one day, the background thread has only a few data updates, at most once an hour. The updated data comes from the network, so it is not sensitive to the timeliness of updates. MAP has a small amount of data, with more than one thousand data records.

The simplest synchronization method is to use a read/write lock, a read lock on the working thread, and a write lock on the background thread. However, the overhead of read/write locks is higher than that of normal mutex. If the worker thread can synchronize data with the most common non-reentrant mutex, the read/write locks are not required, and the performance is high. We use shared_ptr to achieve this:

Class mutex;
Class mutexlockguard;

Class customerdata
{
Public:
Customerdata (): Data _ (new map)
{}

~ Customerdata ();

Int query (const string & customer, const string & stock) const
{
Mapptr DATA = getdata ();
// Once data is obtained, the lock is no longer needed. When retrieving data, only getdata () has internal locks, and the performance of multi-thread concurrent reading is good.

// Assume that the user must exist
Const entrylist & entries = (* Data) [Customer];
Return findentry (entries, stock );
}

Void Update (const string & customer, const entrylist & entries );

PRIVATE:
Typedef vector <string, int> entrylist;
Typedef Map <string, entrylist> map;
Typedef tr1: shared_ptr <map> mapptr;

Static int findentry (const entrylist & entries, const string & Key) const
{/* Use lower_bound to find the key in entries */}

Mapptr getdata () const
{
Mutexlockguard lock (datamutex _);
Return data _;
}

Mapptr data _;
Mutable mutex datamutex _;
};

The key is how to write customerdata: Update. Now that you want to update data, you must lock it. If other threads are reading data at this time, you cannot modify the original data. You must create a copy and modify it on the copy, after modification, replace it. If no user is reading the data, the data can be directly modified to save one copy.

Void customerdata: Update (const string & customer, const entrylist & entries)
{
Mutexlockguard lock (datamutex _);
If (! Data _. Unique ())
{
Mapptr newdata (new map (* Data _));
Data _. Swap (newdata );
}
Assert (Data _. Unique ());
(* Data _) [Customer] = entries;
}

Note that shared_ptr: Unique () is used to judge whether someone is reading the data. If someone is reading the data, we cannot directly modify it because query () does not lock the entire process, only getdata () internal lock. Shared_ptr: swap () replaces data _ with a new copy, and we are still in the lock, so there will be no other threads to read it. You can update it with confidence.

According to our test, in most cases, the update is performed on the original data, and the copy ratio is less than 1%, which is very efficient. More accurately, This is not copy-on-write, but copy-on-other-reading.

We may adopt a lockless data structure in the future, but this implementation is already very good and meets our requirements.

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.