gpt4 book ai didi

c++ - 使用 std::promise 和 std::future 时发生访问冲突

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

在我的代码中,我使用或多或少看起来像这样的结构将任务分派(dispatch)到我的线程池:

working_data get_data(my_thread_pool & thread_pool) {
size_t thread_pool_size = thread_pool.size();
std::vector<working_data> data(thread_pool_size);
std::vector<std::promise<void>> promises(thread_pool_size);

std::mutex data_0_mutex;

for(size_t i = 0; i < thread_pool_size; i++) {
thread_pool.post_task([&, i] {
std::unique_lock<std::mutex> lock(data_0_mutex, std::defer_lock);
if(i == 0)
lock.lock();
data[i].add_data(process_data());
if(i != 0) {
lock.lock();
data[0].merge_from(data[i]);
}
promises[i].set_value();
});
}

for(size_t i = 0; i < thread_pool_size; i++) {
promises[i].get_future().wait();
}

return std::move(data[0]);
}

虽然这不是每次我执行此代码时都会发生,但在执行它时多次,此代码会导致访问冲突。

相反,以下代码永远不会导致访问冲突,但我宁愿不使用它,因为我不喜欢在最后使用轮询循环:

working_data get_data(my_thread_pool & thread_pool) {
size_t thread_pool_size = thread_pool.size();
std::vector<working_data> data(thread_pool_size);
std::vector<std::atomic_bool> flags(thread_pool_size);

std::mutex data_0_mutex;

for(size_t i = 0; i < thread_pool_size; i++) {
thread_pool.post_task([&, i] {
std::unique_lock<std::mutex> lock(data_0_mutex, std::defer_lock);
if(i == 0)
lock.lock();
data[i].add_data(process_data());
if(i != 0) {
lock.lock();
data[0].merge_from(data[i]);
}
flags[i].store(true, std::relaxed_memory_order);
});
}

for(size_t i = 0; i < thread_pool_size; i++) {
while(!flags[i].load(std::relaxed_memory_order))
std::this_thread::yield();
}

return std::move(data[0]);
}

请注意,主要区别在于我使用的是 std::atomic_bool 而不是 std::promisestd::future .

错误很可能是在我的 [2000 多行] 代码中的其他地方引起的,但我想知道我在这里展示的代码中是否存在明显的错误。

编辑:

我观察到的另一件事:如果关闭优化,我将无法重现错误。此错误仅在打开优化时发生。

双重编辑组合:

发生访问冲突的调用堆栈不可读:

Call Stack

最佳答案

问题是时间问题。

当最后一个线程设置它的 promise 值时,这允许主线程中的循环完成,这反过来导致 data_0_mutex 对象被销毁。最后一个线程仍然可以运行,并且当 lock 的析构函数被调用时,它引用的互斥量已经(或正在)被销毁。

这在您的“轮询”版本中不太可能是问题,因为主线程必须等待操作系统恢复它,但它仍然可能发生。

解决方案是在设置 promise 之前通过调用释放锁

lock.unlock();

promise[i].set_value(); 之前。

关于c++ - 使用 std::promise 和 std::future 时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42865513/

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