2

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

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();
}

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

4

2 回答 2

4

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

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

此外,我认为对象抽象同步没有任何问题——这在某些(不是全部)情况下是有意义的。

于 2013-05-31T08:31:22.360 回答
1
  1. 我在您的代码中看不到任何问题。而且...是的,现在的代码是线程安全的(除了你会抛出一些异常update_score
  2. bool也许从update_score_safefalse如果try_lock()失败以及true在其他情况下)返回会更好?
  3. 在我看来,将互斥锁公开是一个非常糟糕的主意
  4. 你为什么不使用std::vector
于 2013-05-31T08:17:38.983 回答