C++ 线程锁 mutex 理解 附代码

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值