在多线程应用程序中使用向量

时间:2012-03-24 02:24:23

标签: c++ multithreading stdvector

我一直在为我正在编写的多线程应用程序的问题感到困惑。简而言之,主线程启动一个加载线程,它接受文件对象的列表(向量),检查它们的时间戳,并将更改的文件传递给另一个向量。

当我尝试将新文件添加到需要检查的文件列表时,会出现问题。热加载线程不断检查其列表中的文件是否有变化,在迭代时使用作用域锁定锁定/解锁互斥锁。类似地,当主线程调用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()。

这可不难,但我没有看到任何暗示我尚未尝试过的解决方案......

编辑:

  1. 下面的评论提醒我指出,如果我不调用addItems(),则run()函数似乎不会对应用程序性能产生任何重大影响,但可能会造成浪费。

2 个答案:

答案 0 :(得分:2)

你在哪个平台上?如果您正在尝试查看已更改的文件,则可以使用操作系统工具来高效地执行此操作。在Linux上将是inotify。如果你在Windows上,这看起来很好:http://qualapps.blogspot.co.uk/2010/05/understanding-readdirectorychangesw.html

答案 1 :(得分:1)

您的锁将花费很少的时间解锁。根据{{​​1}}的实施方式,如果确实存在任何延迟,我预计延迟会非常短暂。您列表中的内容越多,YieldCurrentThread在向向量添加数据之前需要等待的平均时间越长。如果你的主线程花了很多时间来调用addItems,我肯定会期待一些放缓。

你可以尝试的一件事是一个如下所示的线程循环:

addItems

这里的想法是采取繁重的处理并将其从互斥锁下移出。当然,如果您的实际瓶颈是锁定争用,这实际上只会加快速度。如果问题只是更多文件需要更多时间来检查,那么它与多个线程无关。