Я сейчас экспериментирую с QSharedMemory
и QProcess
в PyQt.Поэтому я написал небольшое приложение для запуска процесса, который создает сегмент общей памяти и записывает в него данные.Приложение считывает данные обратно, когда процесс записывает на выходе.
К сожалению, я получаю эту ошибку, когда приложение пытается подключиться к сегменту общей памяти: QSharedMemory::handle: doesn't exist
.Кажется, что родительский процесс не может получить доступ к сегменту памяти шейдера, выделенному дочерним процессом, если только сегмент памяти не выделен самим родителем.
Выходная трассировка:
process state: Starting
process state: Running
process started
process output: Done writing to shared memory
Error accessing shared memory from parent process QSharedMemory::handle: doesn't exist
Error accessing data
process state: Not running
process finished
Код моего приложения:
from PyQt4 import QtGui, QtCore
import sys
import pickle
class Widget(QtGui.QWidget):
def __init__(self):
super(Widget,self).__init__()
# create process
self.p = QtCore.QProcess(self)
# Connect to process output
self.p.readyReadStandardOutput.connect( self.on_process_output )
self.p.readyReadStandardError.connect( self.on_process_error_output )
self.p.stateChanged.connect(self.on_process_state_change)
self.p.finished.connect(self.on_process_finished)
self.p.started.connect(self.on_process_started)
self.p.error.connect( self.on_process_error )
self.key = 'share_mem_key'
self.shmem = QtCore.QSharedMemory( self.key )
self.p.start( 'python.exe shmem_process_test.py "%s"' % self.key )
def on_process_output(self):
s_out = bytes.decode( bytes( self.sender().readAllStandardOutput() ) )
print 'process output: %s' % (s_out)
if not self.shmem.isAttached() and not self.shmem.attach():
print 'Error accessing shared memory from parent process: %s ' % self.shmem.errorString()
self.shmem.lock()
try:
data = self.shmem.data()
if data:
print pickle.loads(data.asstring())
finally:
print 'Error accessing data'
self.shmem.unlock()
def on_process_error_output(self):
s_out = bytes.decode( bytes( self.sender().readAllStandardError() ) )
print 'process output: %s' % (s_out)
def on_process_state_change(self,new_state):
states = ["Not running", "Starting", "Running"]
print 'process state: %s' % (states[new_state])
def on_process_finished(self):
print 'process finished'
def on_process_started(self):
print 'process started'
def on_process_error(self):
print 'process error'
# application loop
app = QtGui.QApplication(sys.argv)
widget = Widget()
widget.show()
app.exec_()
Мой код процесса:
from PyQt4 import QtCore
import ctypes
import ctypes.util
import pickle
import sys
CLIB = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
def main(argv):
key = argv[1]
# write to shared memory
data = range(50)
data_bytes = pickle.dumps( data, pickle.HIGHEST_PROTOCOL)
data_len = len(data_bytes)
shmem = QtCore.QSharedMemory(key)
if not shmem.create(data_len):
sys.stderr.write( 'ERROR: shared memory creation' )
sys.stderr.flush()
return
if not shmem.isAttached() and not shmem.attach():
sys.stderr.write( 'ERROR: shared memory access' )
sys.stderr.flush()
return
shmem.lock()
try:
CLIB.memcpy(int(shmem.data()), data_bytes, data_len)
finally:
shmem.unlock()
sys.stdout.write( "Done writing to shared memory" )
sys.stdout.flush()
if __name__ == '__main__':
main(sys.argv)