共享模式在共享访问中是啥意思?
Posted
技术标签:
【中文标题】共享模式在共享访问中是啥意思?【英文标题】:What does shared mode mean in shared access?共享模式在共享访问中是什么意思? 【发布时间】:2021-06-28 17:57:54 【问题描述】:在多线程中,有一个叫做shared_mutex
的东西。当有shared_mutex
时,有两种访问方式。共享访问和独占访问。我已经知道什么是独占访问,但什么是共享访问?据此:https://***.com/a/46050121/15976718,“共享访问允许多个线程获取互斥锁,但它们都只能在共享模式下。”他所说的共享模式是什么意思?共享模式有什么作用?在共享模式下,你可以做与独占访问相同的事情吗?
【问题讨论】:
en.cppreference.com/w/cpp/thread/shared_mutex 您提到的答案甚至给出了一个例子,只读与读写访问。我不明白你不清楚其中的哪一部分。 【参考方案1】:您可以将它们视为读取器和写入器锁。
假设您使用共享互斥锁保护一个整数。
只要没有线程正在写入,您就可以安全地让两个线程读取它。但是,如果任何线程正在编写它,则不应有其他人在阅读它,也不应由其他人编写它,否则您将面临竞争条件的风险。
所以规则是
-
任何数量的线程都可以在共享模式下持有互斥锁。
如果任何线程以独占模式持有互斥锁,则根本没有其他线程可以以任何模式持有互斥锁。
有一些细节,但这应该让你直觉地理解如何使用它,并把细节挂起来。
当使用 C++ std
容器时,您可以使用共享互斥锁来保护它,并对 const
操作使用共享锁,对非const
操作使用独占锁,并避免基于 C++ 内存模型竞争的竞争条件。 (它仍然不作曲,但还不错)。举个例子。
template<class T>
struct shared_mutex_guarded
template<class F>
auto read(F&& f)const
auto l = lock();
return f(t);
template<class F>
auto write(F&& f)
auto l = lock();
return f(t);
shared_mutex_guarded(T tin):
t(std::forward<T>(tin))
private:
mutable std::shared_mutex m;
T t;
auto lock() const
return std::shared_lock(m);
auto lock()
return std::unique_lock(m);
;
测试代码:
auto start = std::chrono::steady_clock::now();
shared_mutex_guarded vec = std::vector<int>1,2,3;
std::jthread a0([&]
using namespace std::chrono;
while(duration_cast<seconds>(steady_clock::now()-start).count() < 3)
std::this_thread::sleep_for( 100ms );
std::stringstream ss;
vec.read([&](auto& vec)
std::cerr << "Working...\n";
for (auto i:vec)
std::this_thread::sleep_for( 10ms );
ss << i << ",";
ss << "\n";
std::cerr << "Solved!\n";
);
std::cerr << ss.str();
);
std::jthread a1([&]
using namespace std::chrono;
while(duration_cast<seconds>(steady_clock::now()-start).count() < 3)
std::this_thread::sleep_for( 100ms );
std::stringstream ss;
vec.read([&](auto& vec)
std::cerr << "Summing...\n";
int sum = 0;
for (auto i:vec)
std::this_thread::sleep_for( 10ms );
sum += i;
ss << "Sum is " << sum << "\n";
std::cerr << "Summed!\n";
);
std::cerr << ss.str();
);
std::jthread b([&]
using namespace std::chrono;
while(duration_cast<seconds>(steady_clock::now()-start).count() < 3)
std::this_thread::sleep_for( 100ms );
vec.write([&](auto& vec)
vec.push_back(vec.back()+1);
for (auto& i:vec)
i *= 2;
);
);
【讨论】:
以上是关于共享模式在共享访问中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章
EGit 的“自动共享位于 git 存储库中的项目”选项是啥意思?