我考虑实施POSIX,但这个问题更多的是关于架构。
我从一个有几个主要工作要做的更新循环开始。我可以将这些作业分为四个或五个具有共同内存访问要求的主要任务。我的想法是将这些工作分解为自己的线程,并让它们完成一个“更新”周期并一直睡到下一帧。
但如何同步?如果我在每个循环开始时分离四个或五个线程,让它们运行一次,死掉,然后在每次传递时分离另外4-5个线程?这听起来很贵。
创建这些线程听起来更合理,让它们进入睡眠状态,直到同步调用唤醒它。
这是明智的做法吗?我愿意接受从想法到任何类型的实现的回应。
编辑:根据目前为止的答案,我想补充一下:
答案 0 :(得分:2)
这取决于线程执行的任务的粒度。如果他们正在执行长任务(例如一秒或更长时间),那么与线程正在进行的工作相比,创建和销毁线程的成本可以忽略不计,因此我建议保持简单并按需创建线程。 / p>
相反,如果你的任务很短(例如不到10-100毫秒),你肯定会开始注意到创建和销毁大量线程的成本。在这种情况下,是的,你应该只创建一次线程并让它们休眠直到工作到达它们。你会想要使用某种condition variable(例如pthread_cond_t
):线程等待条件变量,当工作到达时,你会发出条件变量的信号。
答案 1 :(得分:1)
最好的可能是使用任务队列。
任务队列可以看作等待作业提交给它们的线程。如果一次发送多个,则按FIFO顺序执行。
这样,您可以维护4-5个线程,并且每个线程都执行您为其提供的作业,而无需为每个作业分离新线程。
唯一的问题是我不知道C中任务队列的很多实现.Apple有Grand Central Dispatch就是这样做的; FreeBSD也有它的实现。除了那些,我不知道任何其他。 (不过,我看起来并不是很努力。)
答案 2 :(得分:1)
如果你在每个周期都做同样的工作,并且你需要在下一个周期开始之前等待所有工作完成,那么你正在考虑正确的解决方案。
您需要一些同步对象:“帧开始信号量”,“帧结束信号量”和“帧结束事件”。如果每帧有n个独立任务,则启动n个线程,其循环看起来像这样(伪代码):
while true:
wait on "start of frame semaphore"
<do work>
enter lock
decrement "worker count"
if "worker count" = 0 then set "end of frame event"
release lock
wait on "end of frame semaphore"
然后您可以运行控制器线程:
while true:
set "worker count" to n
increment "start of frame semaphore" by n
wait on "end of frame event"
increment "end of frame semaphore" by n
这适用于小n。如果完成每个循环所需的任务数量变大,那么您可能希望使用与任务队列耦合的线程池,这样您就不会使用线程来淹没系统。但是这个解决方案的复杂性更高,并且线程复杂性是敌人。
答案 3 :(得分:0)
您的想法被称为线程池。它们存在于WinAPI,Intel TBB和Visual Studio ConcRT中,我对POSIX知之甚少,因此无法帮助您,但它们是一个具有许多理想属性的优秀结构,例如出色的扩展,如果发布的工作可以分开。
但是,我不会忽略工作所需的时间。如果你有五个任务,并且你的性能问题如此迫切以至于多个线程是关键,那么创建线程几乎肯定是一个可以忽略不计的问题。