C++ 线程锁 mutex 理解 附代码
1. 概述
对C++里面的mutex相关知识进行梳理,理解线程锁。
2. 理解
mutex英文含义如下,表示一种不相容的性质。
mutex
n. 互斥;互斥元,互斥体;互斥量
- C++里面的mutex类是用来进行
线程同步,保护数据的,防止不同线程对同一数据同时进行处理。如果不使用线程锁会使程序不稳定,达不到预期的效果。 - 它实际上是用来
对线程进行处理的,不是直接处理数据。不同的线程只有拿到了线程锁才可以继续运行,否则需要等待其他线程解除线程锁。 - 线程进行同步时需要进行线程锁的
加锁、解锁的操作。如果加锁之后没有及时解锁可能会导致死锁现象。因为其他线程会等待其他线程解除线程锁,如果一直等不到,可能会一直处于阻塞的状态。
boost中的锁有
class mutex
typedef mutex try_mutex;
class timed_mutex
typedef unique_lock<mutex> scoped_lock;
typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
3. boost::mutex
C++使用线程锁时最简单的就是使用boost::mutex。
3.1 无锁
如果不使用线程锁,代码示例如下
使用命令
g++ nomutextest.cpp -o nomutex -lboost_system -lboost_thread
#include <boost/thread/thread.hpp>
#include <iostream>
#include <iomanip>
#include <unistd.h>
/*
* g++ nomutextest.cpp -o nomutex -lboost_system -lboost_thread
*/
int num = 5;
void helloA()
{
std::cout << "****I'm thread A ! " << boost::this_thread::get_id() << " --- Start " << std::endl;
std::cout << "****I'm thread A the num is "<<num <<std::endl;
num++;
std::cout << "****I'm thread A the num+1 is "<<num <<std::endl;
num++;
std::cout << "****I'm thread A the num+1+1 is "<<num <<std::endl;
sleep(1);
std::cout << "****I'm thread A ! --- OVER " << std::endl;
}
void helloB()
{
std::cout << "I'm thread B ! " << boost::this_thread::get_id() << " --- Start " << std::endl;
std::cout << "I'm thread B the num is "<<num <<std::endl;
num--;
std::cout << "I'm thread B the num-1 is "<<num <<std::endl;
num--;
std::cout << "I'm thread B the num-1-1 is "<<num <<std::endl;
std::cout << "I'm thread B ! --- OVER " << std::endl;
}
int main(int argc, char* argv[])
{
// 建立并执行两个线程
boost::thread thrdA(&helloA);
boost::thread thrdB(&helloB);
thrdA.join(); // 等待子线程完成后再继续执行主进程;
thrdB.join();
// 等待两个 join 后才会继续执行
std::cout<< " ==== over ==== "<<std::endl;
return 0;
}
由于线程实际运行时对num处理的先后顺序不一样导致结果不一样。
可能thrdA先对num进行加处理,可以允许
也有可能thrdB先对num进行减处理,可以允许
也有可能thrdA、thrdB对num同时进行处理。禁止这种情况
输出结果可能为下面情况
线程A先对num进行处理
A5 -> A6 -> A7->B7 -> B6 -> B5
****I'm thread A ! 7f01551c6700 --- Start I'm thread B !
****I'm thread A the num is 5
****I'm thread A the num+1 is 6
****I'm thread A the num+1+1 is 7
7f01549c5700 --- Start
I'm thread B the num is 7
I'm thread B the num-1 is 6
I'm thread B the num-1-1 is 5
I'm thread B ! --- OVER
****I'm thread A ! --- OVER
==== over ====
或者
线程B先对num进行处理,
B5 -> B4 -> B3 -> A3 -> A4 -> A5
I'm thread B ! 7ff008235700 --- Start
I'm thread B the num is 5
I'm thread B the num-1 is 4
I'm thread B the num-1-1 is 3
I'm thread B ! --- OVER
****I'm thread A ! 7ff008a36700 --- Start
****I'm thread A the num is 3
****I'm thread A the num+1 is 4
****I'm thread A the num+1+1 is 5
****I'm thread A ! --- OVER
==== over ====
或者
线程A、B同时对num进行处理。
A5 -> A6 -> B6 -> B5 -> B4 -> A5
****I'm thread A ! I'm thread B ! 7f1c044567007f1c04c57700 --- Start --- Start
****I'm thread A the num is 5
****I'm thread A the num+1 is
I'm thread B the num is 6
I'm thread B the num-1 is 5
6I'm thread B the num-1-1 is 4
I'm thread B ! --- OVER
****I'm thread A the num+1+1 is 5
***

本文深入解析C++中的线程锁概念,包括mutex的基本原理、boost::mutex和std::mutex的使用,以及如何避免死锁。通过示例代码演示线程同步中锁的必要性和正确使用方法。
最低0.47元/天 解锁文章
2078

被折叠的 条评论
为什么被折叠?



