C++ Concurrency in Action 03 多线程时共享数据的管理

1. Race conditions 对资源竞争问题的处理

最常用的就是锁机制 mutexes

#include <iostream>
#include <thread>
#include <functional>
#include <chrono>
#include <mutex>
#include <algorithm>
#include <list>

std::list<int> some_list;
std::mutex some_mutex;

void add_to_list(int new_value)
{
    std::lock_guard<std::mutex> guard(some_mutex);
    some_list.push_back(new_value);
}

bool list_contains(int value_to_find)
{
    std::lock_guard<std::mutex> guard(some_mutex);
    return std::find(some_list.begin(), some_list.end(), value_to_find) \
            != some_list.end();
}


void func1()
{
    for(int i=0; i<10; i++)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "thread1, func1" << std::endl;
        add_to_list(i);
    }

    std::cout << "list_contains(8): " << list_contains(8) << std::endl;
}

void func2()
{
    for(int i=10; i<20; i++)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "thread2, func2" << std::endl;
        add_to_list(i);
    }

    std::cout << "list_contains(15): " << list_contains(15) << std::endl;
}


int main()
{
    std::thread t1(func1);
    std::thread t2(func2);

    t1.join();
    t2.join();


    return 0;
}

更合理的方式是应该将list, mutex 以及操作他们的函数封装在类中。

 

2. 使用mutex锁住共享资源时需要注意

Any code that has access to that pointer or reference can now access (and potentially modify) the protected data without locking the mutex. 如果通过指针和引用将被保护的数据传递出来,之后不进行lock也是可以访问的,这时很危险的。

class some_data
{
private:
    int a;
    std::string b;

public:
    void do_something();
};

class data_wrapper
{
private:
    some_data m_data;
    std::mutex m;

public:
    template<typename Function>
    void process_data(Function func)
    {
        std::lock_guard<std::mutex> l(m);
        func(data); //这里通过some_data&引用将data传出去了,
                    //从而外部可以避开锁来修改本来想要lock的数据
    }
};

some_data* unprotected;
void malicious_function(some_data& protected_data)
{
    unprotected = &protected_data;
}

data_wrapper x;

void foo()
{
    x.process_data(malicious_function());
    unprotected->do_something(); //避开了lock,也可以修改数据
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值