今天发文比较多,哈,实在是觉得知识就该及时沉淀下来,时间长了难免记忆会模糊。
OK,直接切入正题,之前http://t.vimer.cn上提过正在开发的fuload压力测试框架,由于是想拿python做胶水语言,所以不可避免的涉及到了进程间通信的问题。
简单来说就是,一个python写的主进程与多个c写的处理进程通信的问题。主进程启动之后,会启动多个c的处理进程,主进程会对处理进程发送数据,并控制处理进程。
这种情况在server的编写中比较常见,为了解耦一般会将接受数据的进程与处理进程分开,在c中的实现一般是主进程先fork出子进程,然后在子进程中调用exec将自身替换为处理进程,进程id不变。这样主进程即可拿到所有的子进程id进行统一管理。
python当然也可以通过这种方式来实现,fork+execv即可完美重现,但是这可是无所不能的python呀,是否有更好的方式呢?
有的!python2.4之后引入了subprocess模块,通过它,我们将不再需要繁琐的调用fork,execv等,其主要函数如下:

详细可参考:http://luy.li/2010/04/14/python_subprocess/
我们来直接看一下我编写的示例代码,主程序(test_signal_send.py):

然后是处理进程(test_signal_recv.cpp)(没有在ouch中直接printf的原因是由于printf在信号处理函数中调用不安全,详细可以参考unix网络编程):

通过

运行,在另一个窗口中输入:

终端结果如下:

在主进程的窗口上输入CTRL+C,再查看进程情况:

OK,这样主进程启动处理进程的问题就解决了,怎么样,简单吧!

接下来是数据通信的问题。
c处理进程间通信的常用方式相信大家都知道:共享内存,消息队列,信号量,管道,信号,socket,文件mmap等。而python中只支持上述列表中的管道,信号,socket,文件mmap。
具体的筛选过程就不说了,只说最终选择的方案是信号+文件mmap的方式。主进程发送给处理进程信号通知数据可读,处理进程从文件mmap中读取数据。
其实前面的例子中已经使用了信号,所以我们主要说一下mmap就行。python中是提供了mmap模块的,我们直接调用即可。
写文件mmap(python)(test_mmap_write.py):

读文件mmap(c)(test_mmap_read.cpp):

先运行:

然后运行./test_mmap_read,输出如下:

OK,完美解决~~这些代码都放到了fuload工程中,大家可以到https://fuload.googlecode.com/svn/trunk/src/slave/test/查看源码。

暂无相关产品

4则回应给“python与c-跨语言级别的进程间通信”

  1. wecing说道:

    虽然在下是emacser,但是这篇文章真的帮了我大忙了……泪目泪目。

    [回复]

    Dante 回复:

    哈哈,喜欢用什么工具并不是分水岭嘛~~~

    [回复]

    wecing 回复:

    对啊……
    可是最后还是决定用socket了,因为要操作二进制的数据流……

    [回复]

  2. Games说道:

    只来学习。不说话

    [回复]

发表评论