我正在开发一个主线程执行某些工作的应用程序(UI的消息循环等),但我还想要第二个线程,它会定期测试是否有可供下载的更新。我还希望主线程有可能要求辅助线程强制检查更新,并且辅助线程要求主线程确认下载更新。
我在现实生活中没有那么多的IPC和多线程经验,所以我不确定应该如何设计这个。我想最终在Windows和POSIX上都有这项工作,但现在让我们关注POSIX。到目前为止,这是我的想法:
辅助线程伪代码:
repeat forever:
check_for_updates()
if (are_any_updates()) {
put the list of available updates on some message queue
send signal SIGUSER1 to main thread
wait for response from that message queue
if (response is positive) download_updates()
}
unblock signal SIGUSER1 on secondary thread
Sleep(one hour)
block signal SIGUSER1
if (any_signal_was_received_while_sleeping)
any_signal_was_received_while_sleeping := false
Sleep(one more hour)
辅助线程上的SIGUSER1处理程序(主线程已请求我们检查更新):
block signal SIGUSER1 (making sure we don't get signal in signal)
any_signal_was_received_while_sleeping := true
check_for_updates()
...
unblock signal SIGUSER1
基本上,主线程使用SIGUSER1要求辅助线程强制检查更新,而辅助线程使用SIGUSER1请求主线程查看消息队列中是否有可用更新,并确认是否应该下载它们
我不确定这是一个好的设计还是它甚至可以正常工作。我的一个问题与处理主线程中收到的SIGUSER1有关,因为它是一个非常大的应用程序,我不确定何时是阻塞和解除阻塞的正确时间(我认为它应该在消息循环中的某个地方)
任何意见都表示赞赏,包括我应该在Windows上使用哪些IPC功能的建议(可能是RPC而不是信号?)。如果我确定线程,我可以完全删除消息队列的使用,但我可能会考虑使用进程代替。我明确地在Windows上使用线程,但我还不确定POSIX。
答案 0 :(得分:1)
您应该强烈考虑使用boost::thread来解决您的问题。它比直接使用posix更易于理解,并且是跨平台的。花点时间使用更好的工具,最终会为自己节省很多精力。
特别是我认为你会发现condition variable能够巧妙地促进你的简单互动。
编辑:
通过正确使用互斥锁和条件变量,您几乎可以做任何事情。另一条建议是encapsulate your threads inside class objects。这允许您编写作用于线程及其数据的函数。在你的情况下,主线程可以有一个像requestUpdateConfirmation()的方法,在这里你可以阻止调用线程并等待主线程在释放调用者之前处理请求。