2011-06-09 107 views
0

我正在尝试使my_class线程安全。访问类数据时替代互斥锁/解锁

class my_class 
{ 
    const std::vector<double>& 
    get_data() const 
    { //lock so that cannot get_data() while setting data 
    lock l(m_mutex); 
    return m_data; 
    } 

    void 
    run() 
    { 
    vector<double> tmp; 
    //some calculations on tmp. 
    { //lock so that cannot get_data() while setting m_data 
     lock l(m_mutex); 
     m_data = tmp; //set the data 
    } 
    } 

private: 
    std::vector<double> m_data; 
    mutex m_mutex; 
    my_class(); //non-copyable 
} 

run()get_data()可以由不同的openmp线程调用,所以我介绍的锁。 (由于我使用openmp,m_mutexlock是围绕omp_init_lock();等命令的RAII包装)。

但是,锁get_data()是创建和销毁昂贵(当我剖析我的代码 - 我打电话get_data()很多昂贵的操作)。

是否可以重新组织my_class来删除锁在get_data()或者这个锁是并行代码的不可避免的代价?

+0

@sbi是的,谢谢,修复它 – Tom 2011-06-09 18:18:14

回答

2

第一步是查看读写锁:这样多个读卡器不会互相阻塞。

下一步将使用无锁或等待操作。网上有很多资源可以比我所能描述的更好。只需要注意一点:无锁方法处理原子(互锁)操作,这意味着数据大小需要很小。如果你走这条路线,你会原子地替换一个指向你的矢量的指针,而不是整个矢量。这意味着你的类会变得更加复杂,并且会处理一些指针和内存管理。

+0

不幸的是,我不认为openmp支持读写锁。我没有听说过无锁并等待免费的操作。我会立即看到他们,谢谢! – Tom 2011-06-09 18:25:17

+0

是的,无锁,我想我想要的。对于下一个人,我发现以下介绍很有用:www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdf – Tom 2011-06-09 20:21:04

0

围绕get_data/run函数使用临界区可能更便宜,不会产生额外的设置/拆卸开销(因为临界区是静态初始化的),但是这也会同步类的其他实例。