python 使用共享内存的方式有多种, 常见的方案是是使用python语言内封的共享内存模块,这里使用的是ctypes直接加载C语言shmxxx系列函数
from ctypes import *
import time
M100 = 100 * (1 << 20)
libc = CDLL("libc.so.6", use_errno=True) # use_error, 如果此项不为 true, 那么 get_errno 将无法获取到此库的错误码
shmget = libc.shmget
shmget.argtypes = [c_int, c_size_t, c_int]
shmget.restype = c_int
shmat = libc.shmat
shmat.argtypes = [c_int, POINTER(c_void_p), c_int]
shmat.restype = c_void_p
class ShmLicensePlateDetection:
def __init__(self) -> None:
shmid_0 = shmget(0x8880, M100, c_int(0o1000 | 0o2000 | 0o666))
if shmid_0 < 0 :
if get_errno() == 17: # EEXIST
shmid_0 = shmget(0x8880, 0, 0)
else:
print("共享内存ID获取失败: errno:", get_errno())
return
print("共享内存ID获取成功: shmid_0: ", shmid_0)
shmaddr_0 = shmat(shmid_0, None, 0);
if cast(shmaddr_0, POINTER(c_int))[0] == -1:
print("共享内存地址获取失败: errno: ", get_errno())
return
print("共享内存地址获取成功: shmaddr_0: ", hex(id(shmaddr_0)))
#str_len = libc.strlen(cast(shmaddr_0, c_char_p))
#print("共享内存地址获取成功: str_len: ", str_len)
shmid_1 = shmget(0x8881, M100, c_int(0o1000 | 0o2000 | 0o666))
if shmid_1 < 0 :
if get_errno() == 17: # EEXIST
shmid_1 = shmget(0x8881, 0, 0)
else:
print("共享内存ID获取失败: errno:", get_errno())
return
print("共享内存ID获取成功: shmid_1: ", shmid_1)
shmaddr_1 = shmat(shmid_1, None, 0);
if cast(shmaddr_1, POINTER(c_int))[0] == -1:
print("共享内存地址获取失败: errno: ", get_errno())
return
print("共享内存地址获取成功: shmaddr_1: ", hex(id(shmaddr_1)))
self.m_shmaddr_0 = shmaddr_0
self.m_shmaddr_1 = shmaddr_1
def callback(_str_):
return b'{ "warning": "license plate detection callback not define!" }'
self.callback = callback
def shmaddr_read(self, addr=None):
if addr == None:
return False, str("addr==None")
str_len = libc.strlen(cast(addr, c_char_p))
if str_len == 0 : #内存中必须有数据才读出
return False, str("len==0")
str_str = string_at(addr, str_len).decode()
libc.bzero(cast(addr, c_char_p), M100)
return True, str_str
def shmaddr_write(self, addr=None, inputstr=b''):
if addr == None or inputstr == b'':
return False
str_len = libc.strlen(cast(addr, c_char_p))
if str_len != 0 : #内存中必须无数据才写入
return False
libc.strcpy(cast(addr, c_char_p), create_string_buffer(inputstr))
return True