C++ 与生产者/消费者(排序)和STL的并发性
我有以下情况:我有两个线程C++ 与生产者/消费者(排序)和STL的并发性,c++,stl,concurrency,C++,Stl,Concurrency,我有以下情况:我有两个线程 thread1,它是一个工作线程,执行算法直到其输入列表大小>0 thread2,它是异步的(用户驱动的),可以将元素添加到要处理的输入列表中 现在,thread1循环执行与以下类似的操作 list input_list list buffer_list if (input_list.size() == 0) sleep while (input_list.size() > 0) { for (item in input_list) {
- thread1,它是一个工作线程,执行算法直到其输入列表大小>0
- thread2,它是异步的(用户驱动的),可以将元素添加到要处理的输入列表中
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)
}
列表输入\u列表
列表缓冲区列表
如果(输入_list.size()==0)
睡觉
while(input_list.size()>0){
用于(输入列表中的项目){
过程(项目);
可能会将项目添加到缓冲区列表中
}
输入\列表=缓冲\列表(或复制)
缓冲区列表=新列表(或清空)
睡眠X毫秒(100
现在,thread2只需将元素添加到buffer_列表(这将是算法的下一步),如果thread1被停止,它可能会唤醒thread1
我试图理解在这种情况下会发生多线程问题,假设我用STL帮助它编程到C++(没有关于线程安全性的假设),当然我也可以访问标准库(比如互斥)。 我希望避免thread2可能出现的任何延迟,因为它绑定到用户界面,并且会造成延迟。我曾考虑使用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);
}
std::set*extBuffer、*innBuffer、*actBuffer;
void thread1Function()
{
actBuffer->clear();
sem_等待(&mutex);
如果(!extBuffer->empty())
交换(actBuffer,extBuffer);
sem_post(和互斥);
如果(!innBuffer->empty())
{
如果(actBuffer->empty())
交换(innBuffer,actBuffer);
如果(!innBuffer->empty()),则为else
actBuffer->insert(innBuffer->begin(),innBuffer->end());
}
如果(!actBuffer->empty())
{
set::迭代器;
for(it=actBuffer.begin;it!=actBuffer.end();+it)
//过程
//可能在缓冲区->插入(…)
}
}
无效螺纹2添加(项目)
{
sem_等待(&mutex);
extBuffer->insert(项目);
sem_post(和互斥);
}
也许我应该打开另一个问题您只需要在插入、删除或访问容器大小时使用互斥锁。您可以开发一个类来封装容器,该类将具有互斥锁。这将使事情保持简单,并且类将处理使用互斥的功能。如果您限制项的访问(函数/接口的公开内容)并使函数变小(仅调用容器类函数enacapsulated in the mutex),它们将相对较快地返回。在这种情况下,您应该只需要在列表中列出 根据系统的不同,如果您有可用的信号量,您可能希望检查它们是否更有效,并使用它们而不是互斥。同样的概念也适用,只是方式不同而已
您可能需要检查保护的概念,以防其中一个线程死亡,您不会遇到死锁情况。如果您担心thread2会因为thread1持有锁而被阻塞很长时间,那么请确保thread1保护只在很短的时间内持有锁 如果您有两个缓冲区列表实例,这可以很容易地实现。所以你的尝试已经在正确的方向上了 每个缓冲区都用指针指向。一个指针用于将项目插入列表(thread2),另一个指针用于处理其他列表(thread1)中的项目。螺纹2的插入操作必须由锁包围 如果thread1处理完所有项,它只需交换指针(例如,使用std::swap),这是一个非常快速的操作,必须由锁包围。不过,只有交换操作。项目的实际处理是无锁的 此解决方案具有以下优点:
你们有什么“标准图书馆”?C++11,boost.thread,pthreads?我实际上是在iOS上开发的,所以我想这只是你提到的pthreads的一个很好的例子:看,这确实是我试图实现的,问题是thread1可以在工作时向
缓冲区列表添加元素,这就是为什么我考虑使用2个缓冲区列表,这样当thread1要交换时,它会将锁带到buffer\u list 2
,将其元素添加到buffer\u list
,然后有效地交换它们。