我有一个使用单线程库的主进程,我只能使用主进程中的库函数。我有一个由父进程生成的线程,它将从网络接收到的信息放入队列中。
我需要能够告诉主进程有东西在队列中。然后它可以访问队列并处理对象。线程无法处理这些对象,因为该库只能由一个进程调用。
我想我需要使用管道和信号。我还从各种新闻组中了解到我需要使用“自我欺骗”管道。
这个场景应该如何实现?
为什么不使用简单的 FIFO(命名管道)?主进程将自动阻塞,直到它可以读取某些内容。
如果它不应该阻塞,则必须可以进行轮询,但可能会占用 CPU。为此目的可能存在一个有效的库。
我不建议使用信号,因为它们很容易出错。如果您仍然想使用它们,我找到的最简单的方法是:
sigwait()
. 它可能必须唤醒另一个处理信号的线程,例如使用条件变量。优点是您不必再担心从处理程序调用哪个函数是安全的。
我强烈建议您使用线程安全队列,例如这个(文章和源代码)。我个人使用过它,使用起来非常简单。API 包含简单的方法,例如 push()、try_pop()、wait_and_pop() 和 empty()。
请注意,它基于Boost.Thread。
“最佳”解决方案在很大程度上取决于您的具体设置。您是否有一个具有主线程和子线程的进程,或者您是否有一个父进程和一个子进程?您使用哪个操作系统和哪个线程库?
最后一个问题的原因是当前的 C++03 标准没有“线程”的概念。这尤其意味着您的操作系统和线程库提供的任何解决方案都是特定于平台的。最便携的解决方案只会在实施过程中对您隐藏这些细节。
特别是,C++ 在其内存模型中没有线程的概念,也没有原子操作、同步、有序内存访问、竞争条件等的概念。
但是,您使用的任何库都可能已经为您的平台上的问题提供了解决方案。