简体   繁体   English

在C ++中所有并行线程中的所有锁定和解锁实例均使用相同的std :: mutex和lock对象

[英]Using same std::mutex & lock object everywhere for all instances of locking and unlocking in all parallel threads in C++

I've 2 threads which access a shared resource: 我有2个线程可以访问共享资源:

Shared resource is the below Doubly linked list: 共享资源是下面的双链表:

std::list<RowColumns> ll;
struct RowColumns
{
   int x;
   float y;
   vector<vector<string> vec2D;
   .....//many other fields;
}

Thread1: Writes data to this shared resource. 线程1:将数据写入此共享资源。

Thread 2: Reads data from this shared resource and writes to a file. 线程2:从此共享资源中读取数据并写入文件。

Both threads run in parallel ie as and when data is written to shared resource by Thread1 , then thread2 should keep reading the data written and write it to a file, for every "X" time interval. 两个线程并行运行,即,当线程1将数据写入共享资源时,线程2应在每个“ X”时间间隔内继续读取写入的数据并将其写入文件。 So, the code of T1 & T2 has many statements where shared resource is accessed. 因此,T1和T2的代码具有访问共享资源的许多语句。 So to avoid hijacking of the shared resource by 1 thread I just lock & unlock for every acess so that I can achieve concurrency and both threads get opportunity to run. 因此,为了避免共享资源被1个线程劫持,我只需为每个访问权限进行锁定和解锁,以便实现并发性,并且两个线程都可以运行。

My query is can I use a same mutex variable everywhere for all instances of locking and unlocking. 我的查询是,是否可以在所有锁定和解锁实例中到处使用相同的互斥变量。 Example to make my question more clear: 使我的问题更清楚的示例:

In below example, as you can see, the same mutex object "singleMutex" is used & also the same "lock1" unique_lock() lock object is used in both T1 & T2 threads for all acceses of the different elements of the shared resource. 在下面的示例中,您可以看到,在T1和T2线程中,共享资源的不同元素的所有访问都使用了相同的互斥对象“ singleMutex”,并且使用了相同的“ lock1” unique_lock()锁定对象。 Will Such usage of using the same mutex & the same lock across all lock & unlock instances work & really serve the mutex purpose ? 在所有锁和解锁实例中使用相同的互斥锁和相同的锁的这种用法是否有效并真正达到互斥锁的目的? As we know mutex variable & lock is not attached to any object or resource, i think it should work. 我们知道互斥变量和锁未附加到任何对象或资源,我认为它应该可以工作。 BUt at the same time I was confuse dbecause, if we use same mutex everywhere then where do we need multiple mutextx ? 因为同一时间让我感到困惑,因为如果我们到处都使用相同的互斥锁,那么在哪里需要多个mutextx?

    std::mutex singleMutex;


Thread1():
{
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      while(someCondition())
      {
          std::unique_lock<std::mutex> lock1(singleMutex);
          RunStatement_ACCESSING_SHARED_RESOURCE();
          lock1.unlock();
          RunStatement_WITH_NO_SHARED_RESOURCE ();
          RunStatement_WITH_NO_SHARED_RESOURCE ();
          RunStatement_WITH_NO_SHARED_RESOURCE ();
          lock1.lock();
          RunStatement_ACCESSING_SHARED_RESOURCE();
          lock1.unlock();
      }
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       std::unique_lock<std::mutex> lock1(singleMutex);
       RunStatement_ACCESSING_SHARED_RESOURCE();
       lock1.unlock();
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       lock1.lock();
       RunStatement_ACCESSING_SHARED_RESOURCE();
       lock1.unlock();

       RunStatement_WITH_NO_SHARED_RESOURCE ();
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       RunStatement_WITH_NO_SHARED_RESOURCE ();
       lock1.lock();
       RunStatement_ACCESSING_SHARED_RESOURCE();
       lock1.unlock();

Thread_2(): 线程_2():

{
      RunStatement_WITH_NO_SHARED_RESOURCE ();

      std::unique_lock<std::mutex> lock1(singleMutex);
      RunStatement_ACCESSING_SHARED_RESOURCE();
      lock1.unlock();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      lock1.lock();
      RunStatement_ACCESSING_SHARED_RESOURCE();
      lock1.unlock();

      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();

      RunStatement_ACCESSING_SHARED_RESOURCE();
      lock1.unlock();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      lock1.lock();
      RunStatement_ACCESSING_SHARED_RESOURCE();
      lock1.unlock();

      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      RunStatement_WITH_NO_SHARED_RESOURCE ();
      lock1.lock();
      RunStatement_ACCESSING_SHARED_RESOURCE();
      lock1.unlock();

I am not sure if you really understand the concept of a mutex.. 我不确定您是否真的了解互斥锁的概念。

A mutex ( mut ual ex clusion) is used to lock the access on a shared resource, eg an integer, a list or any object. 互斥(MUT UAL clusion)用于锁定上的共享资源的访问,例如整数,列表或任何对象。 Even if your resource consists of multiple variables, you only need one mutex. 即使您的资源由多个变量组成,您也只需要一个互斥量。

A good practice is to encapsulate the access on the resource in a function, so you only need to implement the mutex locking once per access function: 一个好的做法是将对资源的访问封装在一个函数中,因此您只需为每个访问函数实现一次互斥锁:

#include <mutex>

int g_resource = 42;
std::mutex g_mutex;

int getResource()
{
    std::lock_guard<std::mutex> lock(g_mutex);
    return g_resource;
    // auto unlocking, when object 'lock' is destroyed on exit of block
}

void incrementResource()
{
    std::lock_guard<std::mutex> lock(g_mutex);
    g_resource++;
}

//...

  • For primitive datatypes I suggest using std::atomic<T> 对于原始数据类型,我建议使用std::atomic<T>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM