我一直在为我正在编写的多线程应用程序的问题感到困惑。简而言之,主线程启动一个加载线程,它接受文件对象的列表(向量),检查它们的时间戳,并将更改的文件传递给另一个向量。
当我尝试将新文件添加到需要检查的文件列表时,会出现问题。热加载线程不断检查其列表中的文件是否有变化,在迭代时使用作用域锁定锁定/解锁互斥锁。类似地,当主线程调用addItems()函数时,同样的互斥锁同样被锁定,并且添加了新文件。
我读过的信息表明,如果正确锁定,这应该没问题,而且确实有效,但结果却经历了非常大的减速。也就是说,如果我将一个文件添加到列表中,程序会不断减慢,就好像线程变得越来越锁定...
代码:
void MyThread::addItems( ItemList newItems )
{
ScopedLock<Mutex> lock( itemMutex_ );
for ( ItemList::iterator it = newItems.begin(); it != newItems.end(); ++it )
{
if ( ... test condition on (*it) ... )
items_.push_back( (*it) );
}
};
void MyThread::run()
{
_done = false;
do
{
YieldCurrentThread();
if ( !isEmpty_ )
{
ScopedLock<Mutex> lock( itemMutex_ );
for ( ItemList::iterator it = items_.begin(); it != items_.end(); ++it )
{
if ( ... test condition on (*it) ... )
updatedItems_.push_back( (*it) );
}
}
}
}
当然,run()函数连续运行,遍历我的items_ vector,使用从另一个线程调用的addItems()函数将项插入到向量中。只有一个线程调用addItems()。
这可不难,但我没有看到任何暗示我尚未尝试过的解决方案......
编辑:
答案 0 :(得分:2)
你在哪个平台上?如果您正在尝试查看已更改的文件,则可以使用操作系统工具来高效地执行此操作。在Linux上将是inotify。如果你在Windows上,这看起来很好:http://qualapps.blogspot.co.uk/2010/05/understanding-readdirectorychangesw.html
答案 1 :(得分:1)
您的锁将花费很少的时间解锁。根据{{1}}的实施方式,如果确实存在任何延迟,我预计延迟会非常短暂。您列表中的内容越多,YieldCurrentThread
在向向量添加数据之前需要等待的平均时间越长。如果你的主线程花了很多时间来调用addItems
,我肯定会期待一些放缓。
你可以尝试的一件事是一个如下所示的线程循环:
addItems
这里的想法是采取繁重的处理并将其从互斥锁下移出。当然,如果您的实际瓶颈是锁定争用,这实际上只会加快速度。如果问题只是更多文件需要更多时间来检查,那么它与多个线程无关。