我有以下情况:我有两个线程
现在,thread1 循环执行类似于以下的操作
list input_list
list buffer_list
if (input_list.size() == 0)
sleep
while (input_list.size() > 0) {
for (item in input_list) {
process(item);
possibly add items to buffer_list
}
input_list = buffer_list (or copy it)
buffer_list = new list (or empty it)
sleep X ms (100 < X < 500, still have to decide)
}
现在 thread2 将只向 buffer_list 添加元素(这将是算法的下一次传递),并且如果线程 1 停止,则可能设法唤醒它。
我试图了解在这种情况下会发生哪些多线程问题,假设我在 STL 的帮助下将其编程为 C++(不假设实现的线程安全),并且我当然可以访问标准库(像互斥锁)。
我想避免使用 thread2 出现任何可能的延迟,因为它绑定(bind)到用户界面并且会造成延迟。我正在考虑使用 3 个列表来避免同步问题,但到目前为止我还不确定。根据这种特定情况,我仍然不确定 STL 中是否有更安全的容器。我不想只是在所有东西之外放置一个互斥锁而失去如此多的性能。
任何建议将不胜感激,谢谢!
编辑:
这是我到目前为止所管理的,想知道它是否线程安全且足够高效:
std::set<Item> *extBuffer, *innBuffer, *actBuffer;
void thread1Function()
{
actBuffer->clear();
sem_wait(&mutex);
if (!extBuffer->empty())
std::swap(actBuffer, extBuffer);
sem_post(&mutex);
if (!innBuffer->empty())
{
if (actBuffer->empty())
std::swap(innBuffer, actBuffer);
else if (!innBuffer->empty())
actBuffer->insert(innBuffer->begin(), innBuffer->end());
}
if (!actBuffer->empty())
{
set<Item>::iterator it;
for (it = actBuffer.begin; it != actBuffer.end(); ++it)
// process
// possibly innBuffer->insert(...)
}
}
void thread2Add(Item item)
{
sem_wait(&mutex);
extBuffer->insert(item);
sem_post(&mutex);
}
也许我应该打开另一个问题
最佳答案
如果您担心由于线程 1 持有锁而导致线程 2 被长时间阻塞,那么请确保线程 1 保证只占用锁很短的时间。
如果您有两个缓冲区列表实例,这很容易实现。所以你的尝试已经朝着正确的方向发展。
每个缓冲区都用一个指针指向。一个指针用于将项目插入列表 (thread2),另一个指针用于处理另一个列表 (thread1) 中的项目。 thread2 的插入操作必须被锁包围。
如果 thread1 处理完所有项目,它只需要交换指针(例如使用 std::swap),这是一个非常快速的操作,必须用锁包围。虽然只有交换操作。项目的实际处理是无锁的。
该解决方案具有以下优点:
关于c++ - 与生产者/消费者(某种)和 STL 的并发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9732939/