我正在编写一个进程间通信模块(进程 A 和进程 B)。

有什么方法可以让 B 中的通信线程在进程 A 完成特定操作后立即运行(解锁),我的意思是,在 A 完成其操作后,B 无需进行任何轮询,也无需 B 等待太多?

管理这些问题的概念/模型/设计模式是什么?(比进程间同步更精确的东西)。您推荐哪些库/方法?

谢谢。

编辑:我正在寻找适合三种主要操作系统的方法:Windows、Apple Mac OS X、GNU/Linux。

有帮助吗?

解决方案

这是一项相当艰巨的工作:

对于 Unix 操作系统,您可以使用:

  • pthread 条件和带有 setpshared 参数的互斥体。

    笔记:它在Linux 2.6、Solaris下支持良好,但不支持FreeBSD和Cygwin(不知道Mac OS X)

  • 对于 Unix,你也可以使用命名信号量,但我不知道它们的支持级别

  • 对于 Windows,有一些事件...

这是一项艰巨的工作,尤其是对于 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处理程序解锁相应的同步工具。

最常见的是使用的select()/轮询()。两者都可以检查几个文件描述符是否有可用的输入。两者都接收一个超时参数 - 这将防止忙等待,其可以消耗100%的CPU。这是为小/中的应用非常适合的解决方案。

另一种方法是使轮询在单独的线程中。

如果你要开发一个大的应用程序这是值得把目光投向 ACE框架提高。这些框架是跨平台解决方案,以及设计和良好的测试。

嗯,根据我的观点和经验,以可移植且简单的方式做到这一点的最佳方法是使用套接字。另外,您还可以在不同的机器上运行两个进程(如果需要)。另外,您还可以扩展通信以处理同步之外的更多内容。

如果您不想轮询,请使用在套接字上等待同步消息的线程。您以阻塞方式读取套接字。当您收到消息时,您使用标准多线程同步来处理同步。在您的情况下,B 应该等到 A 结束,您只需在进程中以阻塞方式读取即可。

为了便于移植,请使用便携式套接字库,例如 促进 或者 p型 管他呢。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top