如何读取锁定多线程 C++ 程序

Posted

技术标签:

【中文标题】如何读取锁定多线程 C++ 程序【英文标题】:How to read lock a multithreaded C++ program 【发布时间】:2017-04-03 22:58:15 【问题描述】:

对于以下带有 openMP 的多线程程序,我可以做些什么来防止其他线程在一个线程写入“stuff”时读取“stuff”向量?

    vector<int> stuff; //Global vector

    void loop() 
    #pragma omp parallel for
       for(int i=0; i < 8000; i++)
          func(i);
       
    

    void func(int& i) 
       vector<int> local(stuff.begin() + i, stuff.end()); //Reading and copying global vector "stuff"

       //Random function calls here

    #pragma omp critical
       stuff.assign(otherstuff.begin(), otherstuff.end()); //Writing to global vector "stuff"
    

【问题讨论】:

How to use lock in openMP?的可能重复 请注意,引用的问题有更多惯用的 OpenMP 答案。 【参考方案1】:

您可以使用互斥锁来同步访问多个线程之间共享的数据:

#include <mutex>

std::mutex g_stuff_mutex;

vector<int> stuff; //Global vector

void loop() 
#pragma omp parallel for
   for(int i=0; i < 8000; i++)
      func(i);
   


void func(int& i) 
   g_stuff_mutex.lock();
   vector<int> local(stuff.begin() + i, stuff.end()); //Reading and copying global vector "stuff"
   g_stuff_mutex.unlock();

   //Random function calls here

#pragma omp critical
   g_stuff_mutex.lock();
   stuff.assign(otherstuff.begin(), otherstuff.end()); //Writing to global vector "stuff"
   g_stuff_mutex.unlock();


【讨论】:

我认为我不再需要带有互斥锁的“#pragma omp critical”? 不,你不再需要那个编译指示了。但是这个解决方案只允许单个线程在任何给定时间访问stuff,无论它是读取器还是写入器。如果您需要允许多读/单写,请考虑使用std::shared_mutex(为读者使用 lock_shared())而不是常规互斥锁。 ...另外,为了最大限度地提高 RAII 的优势,请使用互斥锁所有权包装器(std::lock_guard、std::unique_lock、std::shared_lock 等),而不是直接调用互斥锁成员。 请注意,OpenMP 不正式支持/与 C++ 线程概念互操作。实际上,我认为这会起作用,但它不是特别惯用或定义明确。 考虑只使用 TBB 来处理整个事情。它有一个并行向量类,你不需要 OpenMP 的东西。 (threadingbuildingblocks.org)。它是免费和开源的。它肯定会比混合 OpenMP 和其他类型的锁看起来更干净!

以上是关于如何读取锁定多线程 C++ 程序的主要内容,如果未能解决你的问题,请参考以下文章

可以使用原子来减少在读取的主导多线程程序中的锁定吗?

锁定 std::map C++

C# - 锁定和 StreamWrite 问题(多线程)

如何在 C++ 中的 unordered_map 的并发读取和锁定单线程写入之间交替

如何在实时应用程序中锁定线程[关闭]

多线程环境中的扩展 OVERLAPPED 对象池:在何处以及如何有效地使用锁定