Today I learned about the lock function in multithreading. C++ locks can be divided into mutual exclusion locks, read-write locks (shared locks), and recursive locks;
std::mutex mutexx;//普通锁互斥锁 //包含在头文件<mutex>
std::recursive_mutex recursive_mutexx; //递归锁 //包含在头文件<recursive_mutex >
std::shared_mutex shared_mutexx; //读写锁 //包含在头文件<shared_mutex>
Mutex locks are created to avoid data competition, that is, to prevent multiple threads from accessing the same data at the same time. When a thread adds a mutex lock, other threads block and wait for the thread's lock to be released after the lock is acquired. Take the following code as an example.
void helloguangzhou()
{
int i = 10;
while (i--) {
cout << " hello guangzhou" << endl;
}
}`
void hellowworld()
{
int i = 10;
while (i--)
{
cout << " hello world" << endl;
}
}
int main()
{
std::thread t1(helloguangzhou);
std::thread t2(hellowworld);
t1.detach();
t2.detach();
system("pause");
return 0;
}
The output is shown below, which looks confusing.
hello guangzhou hello world
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello world
hello world
hello guangzhou
hello world
hello guangzhou
hello world
hello world
hello guangzhou
hello world
hello world
hello world
hello world
If the two thread functions are locked separately, that is
std::mutex mutexx;
void helloguangzhou()
{
mutexx.lock();
int i = 10;
while (i--) {
cout << " hello guangzhou" << endl;
}
mutexx.unlock();
}`
void hellowworld()
{
mutexx.lock();
int i = 10;
while (i--)
{
cout << " hello world" << endl;
}
mutexx.unlock();
}
Then its output is
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
The read-write lock is for when multiple threads access the same data, only one thread can modify the data, and other threads can only access it.
Read-write locks are divided into two types: read mode and write mode. In read mode, the thread in write mode is blocked, and other read mode threads can access, that is, read mode is shared;
in write mode, write mode is blocked in read mode, and other write mode threads are blocked. Also blocked, that is, write unique. This satisfies the condition that only one thread of the read-write lock can modify the data, and multiple threads can access the data at the same time.
The write mode uses lock(), unlock(), unique_lock and other methods to determine the lock and unlock, and the read mode uses share_lock(), share_unlock(), shared_lock and other methods to determine the lock and unlock.
std::shared_mutex shared_mutexx;
void readData()
{
}
Recursive lock, the effect of recursive lock is the same as that of ordinary mutex. The difference between it and ordinary mutex is that it can falsely lock and unlock multiple times, and the number of unlocks should be the same as the number of locks.
This feature comes in handy when two functions foo and goo acquire the same lock, and function foo needs to call goo.