C++标准线程库之共享资源

多线程下难免会需要资源共享,这样难免会发生异常情况。

#include <iostream>
#include <thread>

class X
{
   
    int* _p;

public:
    X(int* p = nullptr) : _p(p) {
   }
    ~X() {
    if(_p) delete _p; }

    void read()
    {
   
        if(_p) std::cout << "value: " << *_p << std::endl; 
    }

    void reset()
    {
   
        if(_p) {
   
            delete _p;			// 2
            _p = nullptr;		// 3
        }
    }
};

int main()
{
   
    X x(new int(77));

    std::thread t1(&X::read, &x), t2(&X::reset, &x);
    t1.join();
    t2.join();

    return 0;
}

在这里插入图片描述

编译运行这个例子可以发现有时代码正常运行输出,而有时却发生了段错误。原因在于指针_p被两个线程共享,会有三种情况:

  • t1 线程已执行过访问_p,t2线程还未执行delete _p,那么就正常输出value: 77
  • t1线程执行完判断还未访问_p就被挂起,t2线程调度成功执行完delete _p,然后t2线程也被挂起,t1线程唤醒继续执行访问 _p造成段错误
  • t2线程执行完了_p = nullptr,t1线程判断 _p,那么就没输出,不过概率不高
  • 还要种情况就留给读者自己思考了,概率也不是很高,主要还是知道会发生异常就行了

所以需要一种方法使得t1线程访问_p时,t2线程不得对 _p就行操作;同理,t2操作时,t1不得读取。

1. 使用互斥量

C++11 提供了互斥量来保护共享数据,思路是线程A在操作共享数据前上锁互斥量,其他线程执行到上锁的互斥量时就会进入阻塞,只有线程A解锁互斥量时, 其他某个线程才能继续上锁,然后那个线程继续执行后续代码。

#include <mutex>

// 互斥量类,不可移动也不可否则
class std::mutex;

void std::mutex::lock();
// 对互斥量进行上锁, 一次只能有线程成功调用此方法并返回,其他线程执行此方法就会进入阻塞状态, 直到unlock方法调用

void std::mutex::unlock();
// 对lock的互斥量继续解锁,以便其他线程可以解除阻塞而返回

bool std::mutex::try_lock();
// 尝试进行上锁操作。若无其他线程上锁,那么上锁互斥量,返回true;若互斥量也被上锁,那么上锁失败返回false

std::mutex::native_handle_type std::mutex::native_handle();
// 返回互斥量的底层标识符, 可用于扩展,但不建议这样用
#include <mutex>

class X
{
   
    int* _p;
    std::mutex mutex;

public:
    X(int* p = nullptr
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值