我正在尝试多线程同步。对于一个背景,我有一套约100000个对象 - 可能更多 - 我想以不同的方式每秒处理多次。通过事件线程同步的开销
现在我最关心的是同步的性能。
这是我认为应该工作得很好(我省略了所有的安全方面,因为这只是一个测试程序,如果出现错误,程序将会崩溃..)。我写了两个funktions,第一个由程序的主线程执行,第二个由所有其他线程运行。
void SharedWorker::Start()
{
while (bRunning)
{
// Send the command to start task1
SetEvent(hTask1Event);
// Do task1 (on a subset of all objects) here
// Wait for all workers to finish task1
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfTask1WorkerEvents>, TRUE, INFINITE);
// Reset the command for task1
ResetEvent(hTask1Event);
// Send the command to start task2
SetEvent(hTask2Event);
// Do task2 (on a subset of all objects) here
// Wait for all workers to finish task2
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfTask2WorkerEvents>, TRUE, INFINITE);
// Reset the command for task2
ResetEvent(hTask2Event);
// Send the command to do cleanup
SetEvent(hCleanupEvent);
// Do some (on a subset of all objects) cleanup
// Wait for all workers to finish cleanup
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfCleanupWorkerEvents>, TRUE, INFINITE);
// Reset the command for cleanup
ResetEvent(hCleanupEvent);
}
}
DWORD WINAPI WorkerThreads(LPVOID lpParameter)
{
while (bRunning)
{
WaitForSingleObject(hTask1Event, INFINITE);
// Unset finished cleanup
ResetEvent(hCleanedUp);
// Do task1 (on a subset of all objects) here
// Signal finished task1
SetEvent(hTask1);
WaitForSingleObject(hTask2Event, INFINITE);
// Reset task1 event
ResetEvent(hTask1);
// Do task2 (on a subset of all objects) here
// Signal finished task2
SetEvent(hTask2);
WaitForSingleObject(hCleanupEvent, INFINITE);
// Reset update event
ResetEvent(hTask2);
// Do cleanup (on a subset of all objects) here
// Signal finished cleanup
SetEvent(hCleanedUp);
}
return 0;
}
要指出我的要求,我只是给你一个小例子: 说我们得到了上述10万点的对象,分成12500个对象中的每个,现代多核处理器的8子集有8个逻辑核心。相关部分是时间。所有任务必须在大约8ms内完成。
我现在的问题是,我能从分割处理中获得显着的提升,还是通过事件的同步过于昂贵?或者如果所有任务都需要这样完成,甚至有另一种方法可以用更少的努力或处理时间同步线程?
这是不可能回答这个不知道更多关于你的任务,他们的资源需求(CPU,I/O)。一般来说,你应该尽量减少你的线程在等待状态下花费的时间。异步处理是线程间信号传递的一种替代方法,但这在您的任务执行中可能不可行。 – 2013-03-19 13:33:13
哦,对不起,完全忘记了我的资源需求。任务1和2是纯粹的CPU,清理仅用于从任务2中延迟删除对象。不幸的是,异步处理是无法替代的任务1,任务2和清理是固定的序列,必须维持顺序,并且必须完成任务可能会开始。 – rootmenu 2013-03-19 14:22:53
这听起来像你可能能够使用OpenMP之类的东西,而不是滚动你自己的线程/信号。这非常适合并行运行类似的顺序任务。 http://msdn.microsoft.com/en-us/library/tt15eb9t(v=vs.110).aspx – 2013-03-19 14:29:29