2011-02-27 152 views
1

我目前正在用PyQt中的QSharedMemoryQProcess进行实验。所以我写了一个小应用程序来启动一个进程,它创建一个共享内存段并向其写入数据。应用程序在输出写入数据时读取数据。父进程无法访问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) 

回答

1

从QSharedMemory文档(重点矿山):

警告: QSharedMemory 以Qt特定的方式更改密钥 。因此, 目前不可能将非Qt应用程序的 共享内存与QSharedMemory一起使用。

不知道你可以做你想做的事(可移植的)。