共享模式在共享访问中是啥意思?

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

【讨论】:

以上是关于共享模式在共享访问中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

samba是啥

EGit 的“自动共享位于 git 存储库中的项目”选项是啥意思?

共享内存在 Linux 中是如何在幕后工作的?

当我对共享库使用“file”命令时,“stripped, with debug_info”是啥意思?

共享 RestAPI 令牌的模式是啥?

__db.001 在伯克利数据库中是啥意思?