线程之间的同步
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
未定义 ...
只需阅读<mutex>
标头
【参考方案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
您有两个访问级别:共享>,多个读取线程可以共享对互斥锁的访问,独占,其中一个单个写入线程具有对该互斥体的独占访问权限。以上是关于线程之间的同步的主要内容,如果未能解决你的问题,请参考以下文章