C ++ summary of locks (a)
Thread lock is divided into two, mutually exclusive locks and shared locks .
Have associated header <mutex>
, <shared_mutex>
the former has std::unique_lock
the operation for realizing mutual exclusion, with the latter std::shared_lock
operation, a shared lock operation is completed.
Here to discuss std::shared_mutex
this class.
Shared lock
If you need to use a shared lock, you need to use std::shared_mutex
this class. Explain in detail see here
The lock can be used to protect a plurality of threads simultaneously access shared data.
std::shared_mutex
There are two levels of access:
- Share: multiple threads can share ownership of the lock. General data for read operations, to prevent the modified data is written.
- Mutually exclusive: only one thread can own the lock. Generally used for write operations.
If a thread has acquired the mutex , other threads can not acquire the lock.
If a thread has acquired shared locks , any other thread can acquire the mutex , but you can get a shared lock .
Here, in order to achieve mutually exclusive and shared the lock, we had to introduce std::shared_lock
and std::unique_lock
two templates. The former definition <shared_mutex>
, after the definition <mutex>
of.
In the following code are tested, the compiler options --std=c++1z -pthread
;
Since c ++ is cout
not thread-safe function, so to cout
output if the mutex.
A shared lock code sample
#include <shared_mutex>
#include <mutex>
#include <iostream>
#include <thread>
#include <chrono>
std::shared_mutex test_lock;
std::mutex cout_lock;
int arr[3] = {11, 22, 33};
void unique_lock_demo(int id)
{
std::unique_lock lock{test_lock};
for(int i =0; i < 3; i++)
{
arr[i] = i + 100 * id;
}
for(int i = 0; i < 3; i++)
{
std::unique_lock pl(cout_lock);
std::cout << "In unique: " << id << ": " << arr[i] << std::endl;
pl.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void shared_lock_demo(int id)
{
std::shared_lock lock{test_lock};
for(int i = 0; i < 3; i++)
{
std::unique_lock pl(cout_lock);
std::cout << "In shared " << id << ": " << arr[i] << std::endl;
pl.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::thread t3(unique_lock_demo,3);
std::thread t4(unique_lock_demo,4);
std::thread t1(shared_lock_demo,1);
std::thread t2(shared_lock_demo,2);
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
The output is:
In unique: 3: 300
In unique: 3: 301
In unique: 3: 302
In shared 1: 300
In shared 2: 300
In shared 1: 301
In shared 2: 301
In shared 1: 302
In shared 2: 302
In unique: 4: 400
In unique: 4: 401
In unique: 4: 402
As can be seen from this output:
If a thread has acquired shared locks , any other thread can acquire the mutex , but you can get a shared lock .
As can be seen from this output to verify if a thread has acquired the mutex , other threads can not acquire the lock.