Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++ 使用std::try_to_lock时出现意外行为_C++_Multithreading_C++11_Locking_Mutex - Fatal编程技术网

C++ 使用std::try_to_lock时出现意外行为

C++ 使用std::try_to_lock时出现意外行为,c++,multithreading,c++11,locking,mutex,C++,Multithreading,C++11,Locking,Mutex,当我尝试运行下面的代码时,会出现令人惊讶和冲突的行为 #include <iostream> #include <mutex> int main() { std::mutex mtx; std::unique_lock<std::mutex> lock1(mtx); std::unique_lock<std::mutex> lock2(mtx, std::try_to_lock); std::cout <&

当我尝试运行下面的代码时,会出现令人惊讶和冲突的行为

#include <iostream>
#include <mutex>

int main() {
    std::mutex mtx;
    std::unique_lock<std::mutex> lock1(mtx);
    std::unique_lock<std::mutex> lock2(mtx, std::try_to_lock);

    std::cout << "lock1 owns lock: " << lock1.owns_lock() << std::endl;
    std::cout << "lock2 owns lock: " << lock2.owns_lock() << std::endl;
}
#包括
#包括
int main(){
std::互斥mtx;
std::唯一锁定锁1(mtx);
std::唯一锁定锁2(mtx,std::尝试锁定);
std::cout如for
std::unique_lock
constructor:

  • 通过调用m.try_lock(),尝试锁定关联的互斥体而不阻塞。如果当前线程已经拥有互斥体,则该行为未定义,除非互斥体是递归的
  • 重点是我的。因为
    std::mutex
    不是递归的,所以您有未定义的行为-

    如果已经拥有互斥锁的线程调用了try_lock,则该行为未定义


    AS在这里回答,根据当前的C++标准,已经锁定了当前线程的互斥体是一个未定义的行为,但是您似乎知道您的实现是基于POSIX线程的,它具有不同的需求集:

    pthread\u mutex\u trylock()函数应与
    
    pthread\u mutex\u lock()
    ,除非 互斥锁当前被任何线程(包括当前线程)锁定() 线程),呼叫应立即返回

    您所观察到的最有可能是由于您不使用<代码> -pTox/Cuff.Fig.Gnu C++库来检测程序是否与<代码> LBPthToX链接。所以如果不是,那么所有调用<代码>锁<代码> >代码>解锁< /代码>函数变成NO-op.< /P> 您可以找到一些信息:

    \uuuu gthread\u mutex\u lock
    是一个单行函数,用于转发到
    pthread\u mutex\u lock
    。如果不链接到
    libpthread.so
    然后
    pthread\u mutex\u lock
    是一个不执行任何操作的函数 直接调用它比花时间检查线程是否正确更快 活跃的

    或者,您可以自己在头文件中检查源代码中的
    std::mutex::lock
    。您将看到如下内容:

    void
    lock()
    {
      int __e = __gthread_mutex_lock(&_M_mutex);
    
      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
      if (__e)
         __throw_system_error(__e);
    }
    
    static inline int
    __gthread_mutex_lock (__gthread_mutex_t *__mutex)
    {
      if (__gthread_active_p ())
        return __gthrw_(pthread_mutex_lock) (__mutex);
      else
        return 0;
    }
    
    如果
    libpthread,则函数
    \uuu gthread\u active\u p
    将返回
    0
    。因此当前进程中不存在
    ,使互斥锁成为禁止操作


    添加
    -pthread
    将解决您的问题,但您不应该依赖于此-如您的案例所示。

    无法使用GCC 8.1.0进行复制。我无法使用任何一个版本进行复制。您是否在编译时使用了
    -pthread
    标志?在不使用
    -pthread
    时可以进行复制,因此我猜您可能缺少该标志?edit:@NathanOliver击败了我:D一些额外的信息:在使用线程相关的东西(例如互斥)时,始终与
    -pthread
    链接是很重要的。不幸的是,在某些情况下,像您这样的程序不会出现链接器错误,但程序会运行正常情况,尽管它的行为有些未定义。