Общая память от C до Python на Raspberry Pi - PullRequest
0 голосов
/ 24 марта 2020

Справочная информация: Цель состоит в том, чтобы разделить память (массивы со знаком int) между программой C и программой Python. Программа C записывает массив вместе с флагом STATUS, который информирует программу python о необходимости ожидания записи всех данных. Как только программа Python читает массив, она обновляет флаг STATUS, который сообщает программе C, что она свободна для записи следующего массива. Этот процесс должен повторяться бесконечно.

Оборудование / ОС: Raspberry Pi 3 под управлением Stretch OS

Программное обеспечение: 1. Python 3.5 с использованием sysv_ip c и numpy 2. C язык скомпилирован с использованием g cc с использованием библиотек: sys / ip c .h и sys / shm.h

Проблема: Флаг STATUS имеет тип int. При установке флага STATUS общей памяти из программы Python кажется, что я не могу установить для него значение int. Я могу только преобразовать int в строку и установить его, но это не желательный подход.

Запрос: Может кто-нибудь продемонстрировать, как записать флаг STATUS в python в целое число?

C Код - производитель массива (первоначально из stackoverflow.com, сообщение: 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

1 Ответ

0 голосов
/ 24 марта 2020

нашел решение:

a=(status).to_bytes(4, byteorder='little',signed=True)           
memory.write(a,0)
...