Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am using PyQT5 and the QSharedMemory class. I am creating a shared memory which can hold up 6 1-byte elements. To copy these elments in the shared memory array I am looping over the elments from the python list like the following snippet:
f = shared_mem.data()
k = f.asarray()
memtocopy = [0,1,2,3,4,5]
for i in range(0,len(memtocopy)):
k[i] = memtocopy[i]
shared_mem.unlock()
Which seems very unpythonic and boilerplate-code like. I am wondering if there is a more suitable way of achieving the same result?
When using
k[:] = memtocopy
k[:] = np.asarray(memtocopy,np.uint8)
It will fail with the error message:
TypeError: can only assign another array of unsigned char to the slice
The whole test code for reproducing looks like the following:
from PyQt5 import QtCore
# Create shared memory and attach it
shared_mem = QtCore.QSharedMemory()
shared_mem.setNativeKey("test")
shared_mem.create(4*6)
shared_mem.attach()
# Fill in
shared_mem.lock()
f = shared_mem.data()
k = f.asarray()
memtocopy = [0,1,2,3,4,5]
# Loop in question
for i in range(0,len(memtocopy)):
k[i] = memtocopy[i]
shared_mem.unlock()
# Read out
shared_mem.lock()
f1 = shared_mem.data()
k1 = f1.asarray()
shared_mem.unlock()
# Test results
if k1[0] == memtocopy[0]:
print("success!")
else:
print("fail!")
–
–
–
–
Here's a simpler approach using struct and memoryview that reads and writes the data with a couple of one-liners
import struct
from PyQt5 import QtCore
shared_mem = QtCore.QSharedMemory()
shared_mem.setNativeKey("test")
shared_mem.create(4*6)
shared_mem.attach()
memtocopy = [0,1,2,3,4,5]
# Fill in
shared_mem.lock()
shared_mem.data()[:] = memoryview(struct.pack('=6i', *memtocopy))
shared_mem.unlock()
# Read out
shared_mem.lock()
# python3
k = memoryview(shared_mem.data()).cast('i')
# python2
# k = struct.unpack('=6i', memoryview(shared_mem.data()))
shared_mem.unlock()
if k[3] == memtocopy[3]:
print("success!")
else:
print("fail!")
finally:
shared_mem.detach()
–
–
–
After a bit of fiddling about, I managed to produce one combination that functioned for me:
a = array.array('i', range(6))
f[:] = buffer(a)
b = array.array('i')
b.fromstring(buffer(f))
This relies on the buffer protocol for reading both ways. It is likely you can use the array directly with your k, and fromstring has been renamed to frombytes in later versions.
In Python 3.4, this worked:
a = array.array('i', range(6))
f[:] = memoryview(a).cast('B')
b = array.array('i')
b.frombytes(memoryview(f))
memoryview replaced buffer, but knew the elements were 4 bytes large, so it required an additional cast.
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.