如何在C和Python之间处理IPC?

时间:2013-04-20 12:30:02

标签: python c ipc

我有一个带有两个进程的应用程序,一个在C中,一个在Python中。 C进程是完成所有繁重工作的地方,而Python进程则处理用户界面。

C程序每秒写入4次大型缓冲区,Python进程读取此数据。到目前为止,AMQP已经完成了与Python进程的通信。我更愿意在两个进程之间设置一些内存共享,以减少开销并提高性能。

我有什么选择?理想情况下,我只是简单地让Python进程直接读取物理内存(最好是从内存而不是磁盘),然后用信号量或类似的东西来处理竞争条件。然而,这是我没什么经验,所以我很感激我能得到的任何帮助。

我正在使用Linux btw。

3 个答案:

答案 0 :(得分:2)

建议#1: 最简单的方法应该是使用TCP。你提到你的数据量很大。除非您的数据量太大,否则使用TCP应该没问题。确保在C和Python中创建单独的线程,以便通过TCP传输/接收数据。

建议#2: Python支持C语言包装。一个流行的包装器是 ctypes - http://docs.python.org/2/library/ctypes.html

假设您通过共享内存熟悉两个C程序之间的IPC,您可以为您的python程序编写一个C-wrapper,它从共享内存中读取数据。

还要检查以下关于python和C ++之间的IPC的讨论: Simple IPC between C++ and Python (cross platform)

答案 1 :(得分:0)

如何将权重提升代码编写为C中的库,然后提供Python模块作为它的包装?这实际上是一种非常常见的方法,特别是它允许在Python中进行原型设计和分析,然后将性能关键部分移动到C。

如果你真的有理由需要两个进程,那么Python中有一个XMLRPC包可以促进这样的IPC任务。在任何情况下,使用现有的框架而不是发明自己的IPC,除非你能真正证明性能需要它。

答案 2 :(得分:0)

这个问题已经问了很长时间了。我相信发问者已经有了答案,所以我为以后来的人们写了这个答案。

/*C code*/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define GETEKYDIR ("/tmp")
#define PROJECTID  (2333)
#define SHMSIZE (1024)

void err_exit(char *buf) {
    fprintf(stderr, "%s\n", buf);
    exit(1);
}


    int
main(int argc, char **argv)
{

    key_t key = ftok(GETEKYDIR, PROJECTID);
    if ( key < 0 )
        err_exit("ftok error");

    int shmid;
    shmid = shmget(key, SHMSIZE, IPC_CREAT | IPC_EXCL | 0664);
    if ( shmid == -1 ) {
        if ( errno == EEXIST ) {
            printf("shared memeory already exist\n");
            shmid = shmget(key ,0, 0);
            printf("reference shmid = %d\n", shmid);
        } else {
            perror("errno");
            err_exit("shmget error");
        }
    }

    char *addr;

    /* Do not to specific the address to attach
     * and attach for read & write*/
    if ( (addr = shmat(shmid, 0, 0) ) == (void*)-1) {
        if (shmctl(shmid, IPC_RMID, NULL) == -1)
            err_exit("shmctl error");
        else {
            printf("Attach shared memory failed\n");
            printf("remove shared memory identifier successful\n");
        }

        err_exit("shmat error");
    }

    strcpy( addr, "Shared memory test\n" );

    printf("Enter to exit");
    getchar();

    if ( shmdt(addr) < 0) 
        err_exit("shmdt error");

    if (shmctl(shmid, IPC_RMID, NULL) == -1)
        err_exit("shmctl error");
    else {
        printf("Finally\n");
        printf("remove shared memory identifier successful\n");
    }

    return 0;
}
#python 

# Install sysv_ipc module firstly if you don't have this
import sysv_ipc as ipc

def main():
    path = "/tmp"
    key = ipc.ftok(path, 2333)
    shm = ipc.SharedMemory(key, 0, 0)

    #I found if we do not attach ourselves
    #it will attach as ReadOnly.
    shm.attach(0,0)  
    buf = shm.read(19)
    print(buf)
    shm.detach()
    pass

if __name__ == '__main__':
    main()

首先需要执行C程序,而不仅仅是在执行python代码之前将其停止,它还会创建共享内存段并向其中写入一些内容。然后,Python代码附加相同的段并从中读取数据。

完成所有操作后,按Enter键停止C程序并删除共享内存ID。

我们可以在这里看到有关Python的SharedMemory的更多信息:  http://semanchuk.com/philip/sysv_ipc/#shared_memory