0

Background: Goal is to share memory (arrays of signed int) between C program and Python Program. The C program writes an array along with a STATUS Flag which informs the python program to wait until all data is written. Once the Python program reads the array it updates the STATUS Flag which informs the C program that it is free to write the next array. This process should repeat indefinitely.

Hardware/OS: Raspberry Pi 3 running Stretch OS

Software: 1. Python 3.5 using sysv_ipc and numpy 2. C language compiled using gcc using libraries: sys/ipc.h and sys/shm.h

Issue: The STATUS Flag is a int type. When setting the STATUS Flag of the shared memory from the Python program it seems that I cannot set it to a int value. I can only convert the int to a string and set it but this is not the desired approach.

Request: Can anyone demonstrate how to write the STATUS Flag in python to an integer?

C Code - array producer (originally from 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 Code

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
  • Take a look at struct.pack Commented Mar 24, 2020 at 16:42

1 Answer 1

1

found the solution:

a=(status).to_bytes(4, byteorder='little',signed=True)           
memory.write(a,0)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.