线程之间的同步

Posted

技术标签:

【中文标题】线程之间的同步【英文标题】:Synchronization between threads 【发布时间】:2019-04-30 13:12:50 【问题描述】:

我是一名学生,我想了解。

我有两个线程 t1 和 t2。

我在他们之间有一段共享的记忆。

/*e.g.*/ std::map<std::string, std::string> data;

一个线程假设 t1 正在读取数据,另一个正在写入..

std::mutex mu; //is used for synchronization

std::string read_1(std::string key)

    return data[key];


std::string read_2(std::string key)

    mu.lock();
    return data[key];
    mu.unlock();


void write(std::string key, std::string value)

    mu.lock();
    data[key] = value;
    mu.unlock();

read_1 它是线程安全的吗?

如果不是优化此代码的最佳方法是什么?

谢谢。

【问题讨论】:

不,read_1 不是线程安全的。我不确定“这段代码”是什么代码——你没有展示太多。 另外,read_2 已损坏 - 它锁定互斥锁,但不解锁。 mu.unlock() 永远无法到达。这将很快导致未定义的行为。 使用 std::unique_lock 之类的东西,而不是手动锁定/解锁互斥锁。 data 未定义 ... 只需阅读&lt;mutex&gt; 标头 【参考方案1】:

没有。 read_1 不是线程安全的。它需要在访问data之前锁定互斥锁。

这样是安全的;

std::string read_1(std::string key)

    std::lock_guard<std::mutex> guard(mu);
    return data[key];

还有;您的 read_2 功能已损坏。它在解锁互斥锁之前返回。如果您使用了std::lock_guard,那么您就不会遇到这个问题。

【讨论】:

感谢您的回复。就 write() + read_2() 未优化而言,优化此问题的最佳解决方案是什么? @RogerWorld 避免互斥锁的唯一方法是重写整个算法。例如,您可以有单独的地图,并偶尔根据需要合并它们。取决于你最终需要做什么。 @RogerWorld 需要优化什么?您是否分析了代码并确定这是一个热点?如果没有,请保持简单并在访问 data 之前锁定互斥锁。【参考方案2】:

read_1 它是线程安全的吗?

不,当可能写入该数据时,它正在读取。

如果不是优化此代码的最佳方法是什么?

也许使用std::shared_mutex。

【讨论】:

感谢@paul evans 的帮助。为什么 shared_mutex?我可以使用第一条评论中建议的互斥锁。 因为std::shared_mutex 您有两个访问级别:共享​​>,多个读取线程可以共享对互斥锁的访问,独占,其中一个单个写入线程具有对该互斥体的独占访问权限。

以上是关于线程之间的同步的主要内容,如果未能解决你的问题,请参考以下文章

线程之间的同步

线程之间的同步

线程同步

进程之间的线程同步

如何在高速线程之间逐线程同步数据?

关于线程之间的通信和同步