【发布时间】:2010-08-16 10:01:13
【问题描述】:
我有一个“主”线程,它创建一组SlowData 类的对象。这些对象操作起来相对较慢。这就是为什么当我最初加载它们时,它们充满了存根数据。
在加载数组中的每个对象后,我可以立即在 UI 中显示该数组。与此同时,我开始对数组进行计算。 SlowDataComputation 对象被指示向 UI 报告结果(这反过来将可视化特定 SlowData 对象的修改)。
这就是它的样子:
void main()
{
std::vector<SlowData> aData;
aData.reserve(1000000); // one million instances
Fast_PopulateVector(aData);
DataUi aUi;
SlowDataComputation aCalc;
aCalc.SetUiCallback(aUi); // instruct the object to periodically
// report computation results to the UI
aCalc.Slow_ComputeInSeveralThreads(aData);
aUi.VisualizeInMessageLoop(aData); // message loop that exits upon user signal
if ( aCalc.StillWorking() )
aCalc.Stop(); // terminate threads gradually
// after VisualizeInMessageLoop returns, aData will then be destroyed
}
我希望SlowDataComputation 启动几个线程,每个线程都会处理数组中的某个段:
class SlowDataComputation
{
std::vector<SlowData> * myData;
DataUi * myUI;
public:
void Slow_ComputeInSeveralThreads(std::vector<SlowData> & theV)
{
myData = &theV;
size_t aSize = myData->size();
size_t aNumThreads = 10;
size_t aBlockSize = aSize / aNumThreads;
for (size_ti = 0; i < aNumThreads; i++)
{
ComputationThread aThr(myData);
aThr.SetBoundary(i * aBlockSize, (i+1) * aBlockSize);
aThr.SetUiCallback(myUI);
aThr.Run(); // process a given segment in the array
}
}
};
最后,这里是一些 UI 的伪代码:
class DataUi
{
std::vector<SlowData> * myData;
public:
void VisualizeInMessageLoop()
{
Message aMsg;
while ( HasMessage(aMsg) )
if (aMsg.Code == Message::MSG_PROGRAM_QUIT)
SignalQuit(); // next time, HasMessage will return false
// return from message loop
}
};
问题是:我如何保护SlowData 实例的销毁,以便如果十个 计算线程中的任何一个当前正在处理一个对象,销毁需要等到每个计算线程完成(因为它完成了处理,或者因为调用了SlowDataComputation::Stop 方法)?哪种同步原语最适合这项任务?
我设法用 一个 计算线程解决了这个问题。我使用了关键部分。但是这种解决方案不能很好地扩展到一个以上的计算线程。
【问题讨论】:
标签: multithreading synchronization shared-memory