title: Parent process can't access shared memory in PyQt
body: <p>I'm currently experimenting with <code>QSharedMemory</code> and <code>QProcess</code> in PyQt. So I wrote a small application to launch a process, which creates a shared memory segment and writes data to it. The application reads the data back when the process writes on the output. </p>
  
  <p>Unfortunately, I get this error when the application attempts to attach to the shared memory segment: <code>QSharedMemory::handle: doesn't exist</code>. It seems like the parent process cannot access the shaderd memory segment allocated by a child process unless the memory segment is allocated by the parent itself.</p>
  
  <p>Output trace:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>My application code:</p>
  
  <pre><code>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_()
  </code></pre>
  
  <p>My process code:</p>
  
  <pre><code>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)
  </code></pre>