gpt4 book ai didi

c++ - STL 和多线程

转载 作者:太空狗 更新时间:2023-10-29 20:00:25 25 4
gpt4 key购买 nike

我知道,当我在多个线程中对单个 STL 容器执行操作时,我需要使用互斥体。但是我想知道这条规则是否有任何异常(exception)。请考虑我正在尝试实现的简化场景。

我有多个线程向容器添加元素,并且操作被互斥锁/解锁包围。然后线程以某种方式通知(例如在 linux 上使用 eventfd)专用于调度此容器中元素的单个线程。我想要做的是在不使用互斥锁的情况下访问容器中的第一个元素。基于双端队列的示例代码,但请注意,我可以使用任何具有队列功能的容器:

std::mutex     locker;
std:deque<int> int_queue;
int fd; // eventfd
eventfd_t buffer;
bool some_condition;

线程 1、2、3 等

locker.lock ();
int_queue.push_back (1);
locker.unlock ();

eventfd_write (fd, 1);

专用于调度元素的线程:

while (true)
{
bool some_condition (true);

locker.lock ();
if (int_quque.empty () == false)
{
locker.unlock ();
}
else
{
locker.unlock ();
eventfd_read (fd, &buffer);
}

while (some_condition)
{
int& data (int_queue.front ());

some_condition = some_operation (data); // [1]
}

locker.lock ();
int_queue.pop ();
locker.unlock ();
}

[1] 我会多次对 signle 元素执行 some_operation() ,这就是为什么我想在这里避免互斥锁。太贵了。

我想知道这段代码是否会导致任何同步问题或其他问题。

最佳答案

您需要的是引用稳定性。 IE。如果当容器被 push_back 时对第一个元素的引用没有失效,则可以这样使用容器。即便如此,您还是希望获得对锁下前面元素的引用。

我更熟悉用于事件通知的 std::condition_variable,所以我将使用它:

#include <mutex>
#include <condition_variable>
#include <deque>

std::mutex locker;
std::deque<int> int_queue;
std::condition_variable cv;

void thread_1_2_3()
{
// use lock_guard instead of explicit lock/unlock
// for exception safety
std::lock_guard<std::mutex> lk(locker);
int_queue_.push_back(1);
cv.notify_one();
}

void dispatch()
{
while (true)
{
bool some_condition = true;
std::unique_lock<std::mutex> lk(locker);
while (int_queue.empty())
cv.wait(lk);
// get reference to front under lock
int& data = int_queue.front();
lk.unlock();
// now use the reference without worry
while (some_condition)
some_condition = some_operation(data);
lk.lock();
int_queue.pop_front();
}
}

23.3.3.4 [deque.modifiers] 关于 push_back 的说法:

An insertion at either end of the deque invalidates all the iterators to the deque, but has no effect on the validity of references to elements of the deque.

这是让您在锁定之外卡在该引用上的关键。如果 thread_1_2_3 在中间开始插入或删除,那么您就不能再卡在这个引用上了。

您不能以这种方式使用vector。但是您可以这样使用 list。检查您要以这种方式使用的每个容器的引用稳定性。

关于c++ - STL 和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7052677/

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