[PyQt] pyqt4 amd multiprocessing

Lic. José M. Rodriguez Bacallao jmrbcu at gmail.com
Mon May 9 14:10:20 BST 2011


I am very interested in the answer because I have plan to use
multiprocessing module to do my hard work (because of the python GIL),
my future design is something like Samuele say, a pool of process
ready to do some hard job (using multiprocessing) and the GUI with
pyqt4 and vtk, data pass back and forth between the gui and the worker
processes (data will be vtk datasets)

On Mon, May 9, 2011 at 6:26 AM, Samuele Carcagno <sam.carcagno at gmail.com> wrote:
> Hi,
>
> I would like to use the multiprocessing module to create a set of sounds (as numpy arrays) in parallel.
> The parameters of the sounds (duration, volume, etc..) are controlled by a pyqt4 GUI, and the sounds
> need to be passed back to the GUI for further processing and presentation. The sounds are generated
> in a separate module from the GUI. I'm attaching a minimal example with a file that creates the gui and
> a second file that contains the functions for generating the sounds.
>
> I've had mixed success so far, it seems to work on Kubuntu Natty - Python 2.7.1+ - Qt 4.7.2 - PyQt 4.8.3
> but sometimes it fails on Kubuntu Lucid -  Python 2.6.5 - Qt 4.6.2 - PyQt 4.7.2  with the following error:
>
> Traceback (most recent call last):
>  File "test_gui.py", line 20, in onClickButton1
>    self.doTrial()
>  File "test_gui.py", line 32, in doTrial
>    x = complexTone(F0, lowHarm, highHarm, level, duration, ramp, channel, fs, maxLevel)
>  File "/media/ntfsShared/mptest/simple_test/stim.py", line 45, in complexTone
>    pool.join()
>  File "/usr/lib/python2.6/multiprocessing/pool.py", line 342, in join
>    p.join()
>  File "/usr/lib/python2.6/multiprocessing/process.py", line 119, in join
>    res = self._popen.wait(timeout)
>  File "/usr/lib/python2.6/multiprocessing/forking.py", line 117, in wait
>    return self.poll(0)
>  File "/usr/lib/python2.6/multiprocessing/forking.py", line 106, in poll
>    pid, sts = os.waitpid(self.pid, flag)
> OSError: [Errno 4] Interrupted system call
>
> Am I doing something fundamentally unsafe by using multiprocessing in this way with a pyqt4 GUI?
> What is the best approach to use multiprocessing together with pyqt4?
>
> Thanks for any suggestions!
>
> Sam
>
> ###---------GUI----------File 1
> from PyQt4 import QtGui
> from PyQt4 import QtCore
> import sys
> from stim import* #import module for stimulus generation
>
>
> class Example(QtGui.QWidget):
>
>    def __init__(self):
>        super(Example, self).__init__()
>        self.setGeometry(300, 300, 250, 150)
>        self.setWindowTitle('Multiprocessing Test')
>
>        self.button1 = QtGui.QPushButton('Button 1', self)
>        QtCore.QObject.connect(self.button1,
>                               QtCore.SIGNAL('clicked()'), self.onClickButton1)
>
>    def onClickButton1(self):
>        self.doTrial()
>
>    def doTrial(self):
>        F0 = 200
>        lowHarm=1
>        highHarm = 20
>        level = 50
>        duration = 180
>        ramp = 10
>        channel = "Both"
>        fs = 44100
>        maxLevel = 100.0
>        x = complexTone(F0, lowHarm, highHarm, level, duration, ramp, channel, fs, maxLevel)
>
>
> if __name__ == '__main__':
>    app = QtGui.QApplication(sys.argv)
>    ex = Example()
>    ex.show()
>    app.exec_()
> #----------END OF FILE 1
>
>
> ###-SOUND GENERATION-- File stim.py
> from numpy import*
> import multiprocessing
>
> def pureTone(frequency, phase, level, duration, ramp, channel, fs, maxLevel):
>
>    amp = 10**((level - maxLevel) / 20.)
>    duration = duration / 1000. #convert from ms to sec
>    ramp = ramp / 1000.
>
>    nSamples = int(round(duration * fs))
>    nRamp = int(round(ramp * fs))
>    nTot = nSamples + (nRamp * 2)
>
>    timeAll = arange(0., nTot) / fs
>    timeRamp = arange(0., nRamp)
>
>    snd = zeros((nTot, 2))
>
>    if channel == "Right":
>        snd[0:nRamp, 1] = amp * ((1-cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[0:nRamp] + phase)
>        snd[nRamp:nRamp+nSamples, 1] = amp* sin(2*pi*frequency * timeAll[nRamp:nRamp+nSamples] + phase)
>        snd[nRamp+nSamples:len(timeAll), 1] = amp * ((1+cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[nRamp+nSamples:len(timeAll)] + phase)
>    elif channel == "Left":
>        snd[0:nRamp, 0] = amp * ((1-cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[0:nRamp] + phase)
>        snd[nRamp:nRamp+nSamples, 0] = amp* sin(2*pi*frequency * timeAll[nRamp:nRamp+nSamples] + phase)
>        snd[nRamp+nSamples:len(timeAll), 0] = amp * ((1+cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[nRamp+nSamples:len(timeAll)] + phase)
>    elif channel == "Both":
>        snd[0:nRamp, 0] = amp * ((1-cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[0:nRamp] + phase)
>        snd[nRamp:nRamp+nSamples, 0] = amp* sin(2*pi*frequency * timeAll[nRamp:nRamp+nSamples] + phase)
>        snd[nRamp+nSamples:len(timeAll), 0] = amp * ((1+cos(pi * timeRamp/nRamp))/2) * sin(2*pi*frequency * timeAll[nRamp+nSamples:len(timeAll)] + phase)
>        snd[:, 1] = snd[:, 0]
>
>    return snd
>
>
> def complexTone(F0, lowHarm, highHarm, level, duration, ramp, channel, fs, maxLevel):
>    pool = multiprocessing.Pool()
>    tn = []
>
>    for i in range(lowHarm, highHarm+1):
>        res = pool.apply_async(pureTone, (F0*i, 0, level, duration, ramp, channel, fs, maxLevel,), callback=tn.append)
>
>    pool.close()
>    pool.join()
>
>    for i in range(len(tn)):
>        if i == 0:
>            snd = tn[i]
>        else:
>            snd = snd + tn[i]
>
>    return snd
>
> #----------END OF FILE 2
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>



-- 
Lic. José M. Rodriguez Bacallao
Centro de Biofisica Medica
-----------------------------------------------------------------
Todos somos muy ignorantes, lo que ocurre es que no todos ignoramos lo mismo.

Recuerda: El arca de Noe fue construida por aficionados, el titanic
por profesionales
-----------------------------------------------------------------


More information about the PyQt mailing list