Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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++;线程死锁示例_C++_Multithreading_C++11_Deadlock - Fatal编程技术网

C++ 如何修复C++;线程死锁示例

C++ 如何修复C++;线程死锁示例,c++,multithreading,c++11,deadlock,C++,Multithreading,C++11,Deadlock,我设计了一个C++11线程死锁。这是通过使用两个单独的函数和一个多线程池来实现的。如何修复此示例以避免死锁?我认为解决方案与锁定过程的一致顺序有关 #include <thread> #include <mutex> #include <iostream> std::mutex kettle; std::mutex tap; #define THREAD_POOL 8 void kettle_tap(){ std::cout <<

我设计了一个C++11线程死锁。这是通过使用两个单独的函数和一个多线程池来实现的。如何修复此示例以避免死锁?我认为解决方案与锁定过程的一致顺序有关

#include <thread>
#include <mutex>
#include <iostream>

std::mutex kettle;
std::mutex tap;

#define THREAD_POOL 8

void kettle_tap(){

    std::cout << "Locking kettle in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex kettle by creating and using lock_guard kettle_lock.
    std::lock_guard<std::mutex> kettle_lock(kettle);
    std::cout << "Locked kettle in " << std::this_thread::get_id() << std::endl;

    std::cout << "Locking tap in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex tap by creating and using lock_guard tap_lock.
    std::lock_guard<std::mutex> tap_lock(tap);
    std::cout << "Locked tap in " << std::this_thread::get_id() << std::endl;

    std::cout << "Filling kettle in " << std::this_thread::get_id() << std::endl;
}

void tap_kettle(){

    std::cout << "Locking tap in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex tap by creating and using lock_guard tap_lock.
    std::lock_guard<std::mutex> tap_lock(tap);
    std::cout << "Locked tap in " << std::this_thread::get_id() << std::endl;

    std::cout << "Locking kettle in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex kettle by creating and using lock_guard kettle_lock.
    std::lock_guard<std::mutex> kettle_lock(kettle);
    std::cout << "Locked kettle in " << std::this_thread::get_id() << std::endl;

    std::cout << "Filling kettle in " << std::this_thread::get_id() << std::endl;

}

int main(){

    std::thread pool[THREAD_POOL];

    for (int t = 0; t < THREAD_POOL; t += 2){
        pool[t]   = std::thread(kettle_tap);
        pool[t+1] = std::thread(tap_kettle);
    }

    for (int t = 0; t < THREAD_POOL; ++t){
        pool[t].join();
    }

    std::cout << "Threads are all joined" << std::endl;

    return 0;

}
#包括
#包括
#包括
std::互斥水壶;
std::互斥抽头;
#定义线程池8
空壶_水龙头(){

std::cout你是对的。死锁可以通过避免循环等待来实现。在你的例子中,为了避免死锁,请在
tap\u kettle
方法中将
cattle\u lock
移动到
tap\u lock
上方的

在您的情况下,
tamp\u tap()
tap\u tamp()
都应该以以下开头:

std::lock(tap, kettle);
但是互斥参数的顺序并不重要,因此两个函数的可能不同

锁定多个互斥锁

锁定作为参数传递的所有对象,必要时阻止调用线程

该函数使用对其成员的未指定调用序列锁定对象。lock,try_lock and unlock可确保所有参数在返回时都被锁定(不产生任何死锁)

如果函数无法锁定所有对象(例如,因为它的一个内部调用引发了异常),则在失败之前,函数首先解锁它成功锁定的所有对象(如果有)

稍后,如果要将锁的所有权转移到
std::lock\u guard

std::lock(tap, kettle);
std::lock_guard<std::mutex> kettle_lock(kettle, std::adopt_lock);
std::lock_guard<std::mutex> tap_lock(tap, std::adopt_lock);
std::锁(水龙头、水壶);
std::锁、护壶、锁(壶、std::采用锁);
标准::锁紧\防护水龙头\锁紧(水龙头,标准::采用锁紧);

非常感谢您在这方面的帮助。啊,太棒了。感谢您的帮助和所有关于这方面的细节。锁采用技巧很好。