Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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++ 增压w/C++;-奇怪的互斥行为_C++_Multithreading_Boost_Boost Thread_Boost Mutex - Fatal编程技术网

C++ 增压w/C++;-奇怪的互斥行为

C++ 增压w/C++;-奇怪的互斥行为,c++,multithreading,boost,boost-thread,boost-mutex,C++,Multithreading,Boost,Boost Thread,Boost Mutex,我正在试验Boost线程,据我所知,我可以编写一个多线程Boost应用程序,并在Windows或Linux中编译它,而我更熟悉的pthreads严格地用于*NIX系统 我有以下示例应用程序: 我通过以下方式编译上述代码: g++ test.cpp -lboost_system -lboost_thread -I"$BOOST_INLCUDE" -L"$BOOST_LIB" 我遇到了一些有趣的矛盾。如果我设置了一个较长的NAP\u持续时间,比如1秒(10

我正在试验
Boost
线程,据我所知,我可以编写一个多线程
Boost
应用程序,并在Windows或Linux中编译它,而我更熟悉的
pthreads
严格地用于*NIX系统

我有以下示例应用程序:


我通过以下方式编译上述代码:

g++ test.cpp -lboost_system -lboost_thread -I"$BOOST_INLCUDE" -L"$BOOST_LIB"
我遇到了一些有趣的矛盾。如果我设置了一个较长的
NAP\u持续时间
,比如1秒(
1000000
),似乎只有线程
1
在完成其操作之前获得互斥锁,而线程
2
在线程
1
完成之前获得锁的情况非常罕见,即使我将“小睡”持续时间设置为几毫秒

当我使用
pthreads
编写类似的应用程序时,锁通常会在线程之间或多或少地随机交替,因为另一个线程已经在互斥锁上被阻塞


因此,对于问题:
  • 这是预期的行为吗
  • 有没有一种方法可以控制这种行为,例如使作用域锁的行为类似于队列中的锁定操作
  • 如果(2)的答案是“否”,是否可以实现类似于
    Boost
    条件变量的功能,而不必担心锁定/解锁调用失败
  • 范围锁定是否保证解锁?我使用RAII方法,而不是手动锁定/解锁,因为解锁操作可能会失败并引发异常,我正在尝试使此代码稳定
  • 多谢各位

    澄清 我知道将调用线程置于睡眠状态不会解锁互斥锁,因为互斥锁仍在作用域内,但预期的调度如下:

    • Thread1锁定,获取互斥锁
    • 螺纹2锁、块
    • Thread1执行并释放锁,然后立即再次尝试锁定
    • Thread2已在等待锁,在thread1之前获取它

      • 你到底为什么感到惊讶? 如果您希望线程2在线程1处于休眠状态时获取互斥,那么,是的,这是预期行为,您的理解是错误的,因为您的锁在范围内


        但是如果您感到惊讶,因为在循环迭代结束时线程1和线程2之间缺乏交替,那么您可以看看关于似乎“不公平”的调度,确切地说,您为什么感到惊讶? 如果您希望线程2在线程1处于休眠状态时获取互斥,那么,是的,这是预期行为,您的理解是错误的,因为您的锁在范围内

        但是,如果您感到惊讶,因为在循环迭代结束时线程1和线程2之间缺乏交替,那么您可以看看似乎“不公平”的调度

        这是预期的行为吗

        是和否。对于哪个线程将获得互斥,您不应该有任何期望,因为它是未指定的。但它肯定在预期行为的范围内

        有没有一种方法可以控制这种行为,例如使作用域锁的行为类似于队列中的锁定操作

        不要这样使用互斥体。别这样。使用互斥体时,只能使它们相对于线程正在执行的其他事情保持很短的时间

        如果(2)的答案是“否”,那么是否有可能实现类似的增压条件变量,而不必担心锁定/解锁调用失败

        当然。编码你想要的

        范围锁定是否保证解锁?我使用RAII方法,而不是手动锁定/解锁,因为解锁操作可能会失败并引发异常,我正在尝试使此代码稳定

        不清楚您担心什么,但建议使用RAII方法

        这是预期的行为吗

        是和否。对于哪个线程将获得互斥,您不应该有任何期望,因为它是未指定的。但它肯定在预期行为的范围内

        有没有一种方法可以控制这种行为,例如使作用域锁的行为类似于队列中的锁定操作

        不要这样使用互斥体。别这样。使用互斥体时,只能使它们相对于线程正在执行的其他事情保持很短的时间

        如果(2)的答案是“否”,那么是否有可能实现类似的增压条件变量,而不必担心锁定/解锁调用失败

        当然。编码你想要的

        范围锁定是否保证解锁?我使用RAII方法,而不是手动锁定/解锁,因为解锁操作可能会失败并引发异常,我正在尝试使此代码稳定


        不清楚您担心的是什么,但建议使用RAII方法。

        只是猜测,但是
        usleep
        是否会使父进程休眠?也许可以尝试使用
        boost::this\u thread::sleep
        。奇怪的是有一个睡眠线程持有一把锁。@JohnnyCage这是一个常见的误解
        usleep
        仅停止调用线程。见讨论。然而,
        这个线程::sleep
        确实更可取哦,我知道
        sleep
        只是挂起调用线程,而不会释放锁。我更关心日程安排。我本以为线程2会在线程1之前执行,因为它已经阻塞了锁,因为它必须重新获取锁。自C++11以来,并发是标准化的,因此您可以直接使用而不是boost。还值得一提的是,
        std::cout
        是缓冲的,不是线程安全的。这可能是个问题。此外,如果可移植性是一个问题,那么Windows上没有
        usleep
        ,只是一个猜测,但没有
        usleep
        放置父进程
        sudo apt-get install libboost-all-dev
        
        g++ test.cpp -lboost_system -lboost_thread -I"$BOOST_INLCUDE" -L"$BOOST_LIB"