2011-02-27 100 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一起使用。

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