用c ++解锁来自另一个进程的线程

时间:2009-08-05 08:56:42

标签: c++ synchronization ipc interprocess

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

一旦进程A完成特定操作,B中的通信线程是否可以运行(解锁),我的意思是在A完成其操作后没有B进行任何轮询或B等待太多?

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

感谢。

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

5 个答案:

答案 0 :(得分:2)

这是一项非常艰苦的工作:

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

  • 使用setpshared参数进行pthread条件和互斥。

    注意:在Linux 2.6,Solaris下支持它,但它不支持FreeBSD和Cygwin(不了解Mac OS X)

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

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

这很难,特别是对于IPC ......

所以如果你想要一些可移植的东西,我建议你看看有条件和互斥的Boost.Interprocess ...

但请确保您要支持的所有操作系统都支持所有功能。

关于Boost.Interprocess

的注意事项

仔细检查您需要使用的每个Unix操作系统的支持级别,因为Boost.Interprosess使用不总是支持的pthread_ *函数...然后返回仿真 - 检查此类仿真的质量

另外,检查这些东西在Windows上是如何工作的 - 据我所知,Win32 API中没有“共享内存”互斥锁,应该使用通常命名的对象,因此请检查支持的内容以及方式。

答案 1 :(得分:1)

编辑:我错误地认为你需要内部线程同步,修改为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_getvalue() <检查当前sem值的完整性/ p>


我认为条件变量适合您要做的事情,这里有一个适用于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下,您可以在Vista下使用pthreads-win32或原生条件变量,有关详情,请参阅MSDN Condition Variables页面。

参考文献:

答案 2 :(得分:0)

如果您的操作系统支持信号,您可以从信号处理程序解锁互斥锁,并在完成任务后立即从进程A发送信号。

进程B将等待互斥或其他同步工具,A将处理任何事情,然后当完成发送信号USR1时,进程B中的USR1处理程序解锁相应的同步工具。

答案 3 :(得分:0)

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

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

如果您要开发一个大型应用程序,那么值得关注ACE frameworkboost。这些框架是跨平台的解决方案,设计精良,经过充分测试。

答案 4 :(得分:0)

嗯,根据我的观点和经验,以便携和简单的方式做到这一点的最好方法是使用套接字。另外,您可以在不同的机器上使用这两个过程(如果需要)。此外,您可以通过交流来处理超过同步的事情。

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

要便携,请使用boostptypes等便携式套接字库。