Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多线程程序中的映射读/写和删除_C++_Multithreading - Fatal编程技术网

C++ 多线程程序中的映射读/写和删除

C++ 多线程程序中的映射读/写和删除,c++,multithreading,C++,Multithreading,在多线程环境下,我在map中有三个读、写和删除功能。 那么它们工作正常吗?或者它们会造成死锁或任何其他类型的错误 我想在多线程程序中读取、写入和删除映射 //Function for read string GetData (const int key) { pthread_rwlock_rdlock(&rwlock); //read lock string result = "not found"; my_map::const_iterator iter =

在多线程环境下,我在map中有三个读、写和删除功能。 那么它们工作正常吗?或者它们会造成死锁或任何其他类型的错误 我想在多线程程序中读取、写入和删除映射

//Function for read 
string GetData (const int key)
{

    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            result = iter->second;
        }
        else
        {
        string = "";
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}

//Function for write
void SetData (const int key)
{

    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            result = iter->second;
        }
        else
        {
            m[key] = "missing data";
            result = "missing data";
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}
//Function for delete
//Function for write
void deleteData (const int key)
{
    pthread_rwlock_rdlock(&rwlock); //read lock
    string result = "not found";
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
        result = iter->second;
    }
    else //missing
    {
        // change from read mode to write mode
        pthread_rwlock_unlock(&rwlock); // unlock read lock
        pthread_rwlock_wrlock(&rwlock); // write lock
        // Try again
        iter = m.find(key);
        if (iter != m.end()) {
            my_map->erase(iter);
        }
        else
        {
        }
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
}

只要您的代码没有其他互斥体,并且不抛出异常,它看起来就正常,不会创建任何死锁

<>异常是你把C风格代码和C++混合时最大的敌人。我建议您研究C++11,但您也可以手动修复它,请参阅下面的直接解决方案。还有更优雅的方式,但最重要的是以某种方式照顾它

其他互斥锁呢?在您的示例中,如果类型
my_map
是用户定义的类型(不是一些标准容器),则它们可以隐藏在该类型中,并且成员函数
find
等也会在内部锁定互斥锁。在其他情况下(不在您的示例中),该值也可能是UDT,而不仅仅是
int
和使用互斥量

代码中有一点很奇怪:为什么
GetData
用写锁锁定互斥锁?这似乎是多余和低效的。另外,对于其他函数,我只需要立即获得写锁,而通常跳过获取读锁。但您可能希望分析这一点,因为两者都可能是有效的用例,并且都可能具有潜在的性能优势

此外,在使用互斥体时,如果可能,请始终将代码移到锁定部分之外。这就是说,
GetData
应该是这样的:

string GetData (const int key)
{
  string result = "not found"; // moved before the lock
  pthread_rwlock_rdlock(&rwlock); //read lock
  try {
    my_map::const_iterator iter = m.find(key);
    if ( iter != m.end() )//found
    {
      result = iter->second;
    }
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    return result;
  }
  catch( ... ) {
    pthread_rwlock_unlock(&rwlock); // unlock read/write lock
    throw;
  }
}

您的代码几乎没有问题;在我看来是这样的

  • e、 g.删除数据;如果您确实在读锁下找到了该记录,您将如何处理它?不删除它?写函数也是如此
  • 为什么要在写和删除函数中使用读锁?为什么不直接使用写锁呢
  • 在read中,为什么要使用写锁
  • 我认为伪代码应该是

    阅读 -带读锁 -找到。存储结果-找到或未找到。 -释放锁 -返回

    写 -取写锁 -写。决定是否覆盖现有密钥。如果不覆盖,您将返回什么?大多数标准实现都设置为覆盖。 -释放锁 -返回

    你的总体方法很好——没有问题

    只有一个锁不能有死锁。要发生死锁,至少需要两个锁和一个特定的模式。e、 g

    线程1 锁(A) 锁(B)

    线程2 锁(B) 锁(A)

    如果线程1在第一次锁调用之后立即跳出,线程2开始工作,则上述情况可能会导致死锁


    如果你想去更具异国情调的地方,并且担心其他潜在的问题,例如,你可以担心优先级反转。我说的是异国情调,因为在大多数情况下,你甚至不必去想它

    这个问题,最肯定的是这个代码,属于。然而,从顶部看,这甚至不可能编译。仅从
    void
    函数返回的值就可以防止出现这种情况。在任何pthread锁定调用中都不会检查潜在的故障条件。您在
    GetData()
    中写入锁定的逻辑被扭曲,并且您的SetData将永远不会向任何插槽写入除“缺少数据”之外的任何内容(调用中没有可设置的值,因此几乎没有意义)。只是为您从代码审查中得到的东西做准备。