仅使用1种方法的类,是否可以安全地处理它自己的互斥体?

时间:2013-05-31 08:07:27

标签: c++ thread-safety mutex

我有一个非常简单的共享数据结构,只有一个类,这个想法是每个线程在进行更新之前首先获取互斥锁:

class SharedData {
private:
    int * score;
    int n_loc;

public:
    mutex mutex;
    SharedData(int n_loc) : n_loc(n_loc) {
        score = new int[n_loc];
    }
    ~SharedData() {
        delete [] score;
    }
    void update_score(int * score2) {
        for(uint i = 0; i < n_loc; ++i) {
            score[i] = score2[i] = max(score[i], score2[i]);
        }
    }
};

该类是否可以处理它自己的互斥锁,例如

void update_score_safe(int * score2, bool force_update = false) {
    if(force_update) mutex.lock();
    else if(!mutex.try_lock()) return;

    update_score(score2);

    mutex.unlock();
}

这段代码现在是否安全?是否会阻止任何代码在没有锁定的情况下调用类(假设我将互斥锁和真正的更新方法设为私有)?

2 个答案:

答案 0 :(得分:4)

不完全;您需要确保它不可复制或可分配。你的'互斥'可能会禁止(std::mutex禁止复制,这是明智的。)

如果它是可复制的和/或可分配的,那么定义语义;即不会锁定或将锁定源复制/分配操作 - 锁定它将是最不令人惊讶的。当然,按原样复制是不安全的(双delete[])但是......

另外,我没有看到抽象同步的对象有什么问题 - 在一些(并非所有)情况下都有意义。

答案 1 :(得分:1)

  1. 我在代码中看不到任何问题。并且......是的,代码现在是线程安全的(除了你将在update_score
  2. 中抛出一些例外
  3. 也许最好从bool返回update_score_safe false如果try_lock()失败,true则在其他情况下?
  4. 在我看来,将互斥体公开是一个非常糟糕的主意
  5. 为什么不使用std::vector