背景: 目標は、C プログラムと Python プログラムの間でメモリ (signed int の配列) を共有することです。C プログラムは、すべてのデータが書き込まれるまで待機するように Python プログラムに通知する STATUS フラグと共に配列を書き込みます。Python プログラムが配列を読み取ると、次の配列を自由に書き込むことができることを C プログラムに通知する STATUS フラグを更新します。このプロセスを無期限に繰り返す必要があります。
ハードウェア/OS: Stretch OS を実行する Raspberry Pi 3
ソフトウェア: 1. sysv_ipc および numpy を使用する Python 3.5 2. ライブラリを使用して gcc を使用してコンパイルされた C 言語: sys/ipc.h および sys/shm.h
問題: STATUS フラグが int 型です。Python プログラムから共有メモリの STATUS フラグを設定するとき、int 値に設定できないようです。int を文字列に変換して設定することしかできませんが、これは望ましいアプローチではありません。
リクエスト: Python で STATUS フラグを整数に書き込む方法を誰か実演してもらえますか?
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