我正在编写一个进程间通信模块(进程 A 和进程 B)。
进程A完成特定操作后,B中的通信线程是否可以运行(解锁),我的意思是在A完成操作后没有B进行任何轮询或B等待太多?
管理这些问题的概念/模型/设计模式是什么?(比进程间同步更精确的东西)。您推荐哪些库/方法?
谢谢。
编辑:我正在寻找适合三种主要操作系统的方法:Ms Windows、Apple Mac OS X、GNU/Linux。
我正在编写一个进程间通信模块(进程 A 和进程 B)。
进程A完成特定操作后,B中的通信线程是否可以运行(解锁),我的意思是在A完成操作后没有B进行任何轮询或B等待太多?
管理这些问题的概念/模型/设计模式是什么?(比进程间同步更精确的东西)。您推荐哪些库/方法?
谢谢。
编辑:我正在寻找适合三种主要操作系统的方法:Ms Windows、Apple Mac OS X、GNU/Linux。
这是一项相当艰巨的工作:
对于 Unix 操作系统,您可以使用:
pthread 条件和带有 setpshared 参数的互斥锁。
注:Linux 2.6、Solaris下支持良好,但不支持FreeBSD和Cygwin(不知道Mac OS X)
对于 Unix,您也可以使用命名信号量,但我不知道它们的支持级别
这是一项艰巨的工作,尤其是对于 IPC...
因此,如果您想要可移植的东西,我建议您查看具有条件和互斥锁的 Boost.Interprocess ...
但请确保您想要支持的所有操作系统都支持所有功能。
关于 Boost.Interprocess 你应该注意的事情
仔细检查您需要使用的每个 Unix 操作系统的支持级别,因为 Boost.Interprosess 使用并不总是支持的 pthread_* 函数......然后失败返回到仿真——检查这种仿真的质量
此外,检查这些东西在 Windows 上的工作方式——据我所知,Win32 API 中没有“共享内存”互斥锁,应该使用通常命名的对象,所以检查支持什么以及如何支持。
编辑:我错误地认为您需要线程间同步,针对 IPC 进行了修订
我认为您需要诸如可等待事件之类的东西。
在 Windows 中,您可以使用CreateEvent()
, 来创建(或获取现有的)命名的自动重置事件。
当进程 A 完成处理时,它应该调用SetEvent()
,而进程 B 应该调用WaitForSingleObject()
休眠直到完成(或超时)。
或者,您可以使用由CreateSemaphore()
, 初始化为 0 的信号量。进程 A 通过调用 表示完成ReleaseSemaphore()
,而进程 B 再次用于WaitForSingleObject()
等待完成。
在 Linux 和 OS X 下,您可以使用信号量达到类似的效果。用于sem_open()
创建命名信号量,初始值为 0。
当进程 A 完成时,它应该调用sem_post()
以增加信号量,而进程 B 应该调用sem_wait()
睡眠直到完成。
注意:信号量方法可能允许发出多个完成信号,您应该通过在 Windows 下设置最大计数来处理这个问题,或者检查当前 sem 值的完整性sem_getvalue()
我认为条件变量适合您尝试做的事情,这是一个适用于 Linux 和 OSX 的示例
#include <pthread.h>
/* no error checking, quick and dirty sample */
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
int a_done = 0;
void init(void)
{
pthread_mutex_init(&g_mutex, NULL);
pthread_cond_init(&g_cond, NULL);
}
void thread_a(void *arg)
{
/* do something here... */
pthread_mutex_lock(&g_mutex);
a_done = 1;
pthread_cond_signal(&g_cond);
pthread_mutex_unlock(&g_mutex);
}
void thread_b(void *arg)
{
/* wait for a to complete */
pthread_mutex_lock(&g_mutex);
while (!a_done)
pthread_cond_wait(&g_cond, &g_mutex);
a_done = 0;
pthread_mutex_unlock(&g_mutex);
}
在 Windows 下,您可以使用pthreads-win32或 Vista 下的原生条件变量,请参阅MSDN 条件变量页面了解更多信息。
参考:
如果您的操作系统支持信号,您可以从信号处理程序解锁互斥锁,并在完成任务后立即从进程 A 发送信号。
进程 B 将等待互斥锁或其他同步工具,而 A 将处理任何事情,然后当完成发送信号 USR1 时,进程 B 中的 USR1 处理程序解锁相应的同步工具。