Raspberry Pi上C和Python之间的共享内存

2024-06-16 08:37:44 发布

您现在位置:Python中文网/ 问答频道 /正文

背景: 目标是在C程序和Python程序之间共享内存(带符号int的数组)。 C程序写入一个数组和一个状态标志,通知python程序等待所有数据写入。一旦Python程序读取数组,它就会更新状态标志,通知C程序可以自由编写下一个数组。这个过程应该无限期地重复

硬件/操作系统:运行Stretch操作系统的Raspberry Pi 3

软件: 1.使用sysv_ipc和numpy的Python 3.5 2.使用gcc使用库sys/ipc.h和sys/shm.h编译的C语言

问题: 状态标志是int类型。在Python程序中设置共享内存的状态标志时,似乎无法将其设置为int值。我只能将int转换为字符串并进行设置,但这不是理想的方法

请求:有人能演示如何将python中的状态标志写入整数吗

C代码-数组生成器(最初来自stackoverflow.com,post:53736985)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>

typedef signed int INT32;
#define  NOT_READY  -1
#define  FILLED     0
#define  TAKEN      1

struct Memory 
{
     INT32  status;
     INT32  pkt_index;
     INT32  data_cnt;
     INT32  data[4];
};

int main()
{
     key_t          ShmKEY=123456; ;
     int            ShmID;
     struct Memory  *ShmPTR;
     INT32 arr[4] = {4,3,2,1};
     int err=0;
     int sec_cnt = 0;

     ShmID = shmget(ShmKEY, sizeof(struct Memory), IPC_CREAT | IPC_EXCL | 0666);
     if (ShmID < 0) 
     {
        // for case of error does not return a valid shmid
        err = errno;
        printf("Error getting shared memory id %d %d\n",ShmID,err);
        if(err == EEXIST) printf("memory exist for this key\n");
        exit(1);
     }

     ShmPTR = (struct Memory *) shmat(ShmID, NULL, 0);
     if ((int) ShmPTR == -1) {
          printf("*** shmat error (server) ***\n");
          exit(1);
     }

     ShmPTR->status = NOT_READY;
     ShmPTR->pkt_index = 1024;
     ShmPTR->data_cnt = 4;
     ShmPTR->data[0]  = arr[0];
     ShmPTR->data[1]  = arr[1];
     ShmPTR->data[2]  = arr[2];
     ShmPTR->data[3]  = arr[3];
     printf("Server has filled %d %d %d %d to shared memory...\n",
            ShmPTR->data[0], ShmPTR->data[1], 
            ShmPTR->data[2], ShmPTR->data[3]);
     ShmPTR->status = FILLED;

     while (ShmPTR->status != TAKEN)
     {
        printf("\r%d %d %d sleeping ...",sec_cnt,ShmPTR->status,ShmPTR->pkt_index);
        fflush(stdout);
        sec_cnt += 1;
        sleep(1);
     }

     shmdt((void *) ShmPTR);
     printf("Server has detached its shared memory...\n");
     shmctl(ShmID, IPC_RMID, NULL);
     printf("Server has removed its shared memory...\n");
     printf("Server exits...\n");
     exit(0);
 }

Python代码

import numpy as np
import sysv_ipc
import sys

# Create shared memory object
ipc_key   = 123456
NOT_READY = -1
FILLED    = 0
TAKEN     = 1

PY_MAJOR_VERSION = sys.version_info[0]

def write_to_memory(memory, status, ofset=0):
    #print("writing %s " % s)
    s = str(status) + '\0'
    if PY_MAJOR_VERSION > 2:
        s = s.encode()
    memory.write(s,offset=ofset)
    return;

try:
    memory = sysv_ipc.SharedMemory(ipc_key,flags=0)
    int_cnt = int(memory.size/4);
    print('int_cnt: ',int_cnt)
    if(int_cnt>3):
        # Read value from shared memory, byte_count=0 means all bytes
        #status = memory.read(byte_count=4,offset=0)
        #print('status:',status)

        memory_value = memory.read(byte_count=0,offset=0)
        c = np.ndarray((int_cnt,), dtype=np.int, buffer=memory_value)

        if(c[0] == FILLED and int_cnt == c[2]+3):
            print('status: ',c[0])
            print('pkt_index: ',c[1])
            print('data_cnt: ',c[2])
            print('data: ',c[3:])
            status = TAKEN

            write_to_memory(memory,status,0)
            #memory.write(status,0) # <-- This results in an exception
            print('done')
        else:
            print('not ready to load, key: ', ipc_key)
            print('status: ',c[0])
            print('pkt_index: ',c[1])
            print('data_cnt: ',c[2])
            print('data: ',c[3:])
except:
    print('Exception: could mean no data')
    pass

Tags: key程序dataincludestatussysintipc