gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:18:50 24 4
gpt4 key购买 nike

我设计了一个 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::lock(Mutexes...)

在您的情况下,kettle_tap()tap_kettle() 都应以:

std::lock(tap, kettle);

但是互斥量参数的顺序无关紧要,因此这两个函数可以不同

Lock multiple mutexes

Locks all the objects passed as arguments, blocking the calling thread if necessary.

The function locks the objects using an unspecified sequence of calls to their members lock, try_lock and unlock that ensures that all arguments are locked on return (without producing any deadlocks).

If the function cannot lock all objects (such as because one of its internal calls threw an exception), the function first unlocks all objects it successfully locked (if any) before failing.

稍后,如果您想将锁的所有权转移给 std::lock_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);

关于c++ - 如何修复 C++ 线程死锁示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25660347/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com