0

I am trying to design a visual stimulus for experiments in my lab. The stimulus should stop when the user presses a key. The entire experiment is timing sensitive and so I cannot run the key check serially.

The code that I wrote looks like this.


class designStim:
    '''
    This is class to hold functions designing the stimulus. There
    are other functions in this class but the only one that is
    called is the following.
    '''
    def deisgnStart(self)
        #This function returns a dictionary variable containing
        #the raw stimulus

class dispStim(threading.Thread):
    def __init__(self,stimdata,q):
        threading.Thread.__init__(self)

    #*Assign the other data from stimdata to self*
    def run(self):
        #Code to run the stimulus

class checkKbdAbort(threading.Thread):
    def __init__(self,q):
        threading.Thread.__init__(self)

    def run(self):
        #Code to check for keyboard key press. In case of key press,
        #use the queue to abort     dispStim*


if __name__ == '__main__':
    a=designStim('test')
    stimdata=a.designStart()
    q=Queue()
    thread1=dispStim(stimdata,q)
    thread2=checkKbdAbort(q)
    thread1.start()
    thread2.start()

This code works when I run serially which leads me to believe that my display scripts are correct. However, when I run the code in this form, the two threads are not run in parallel. thread1 executes and then thread2 runs. During the thread1 run, the stimulus does not display. Is there a mistake I am making during the class initialization/call?

martineau
  • 119,623
  • 25
  • 170
  • 301
Mathew C.
  • 27
  • 2
  • Unfortunately the mistake is... deeper than the code. – Ignacio Vazquez-Abrams Feb 22 '14 at 04:54
  • What would help this is providing a short, self-contained, "correct" example; "correct" meaning that we can take the code and run it ourselves and see the behavior you are seeing. Often going through this exercise is a good way of solving your problem yourself as you learn to narrow your problem down to the smallest thing that will still reproduce the issue, and from there it's often a very small step to actually solve it. (Reference: http://www.sscce.org/) – Vultaire Feb 22 '14 at 05:04

3 Answers3

0

While I cannot answer your question for sure (since I don't see a complete example and thus do not know why things seem to be executing serially), and putting aside what appear to be typos in the code copied into your question, what you are attempting to do appears basically correct. If you subclass threading.Thread and provide a run() definition, and if you launch each thread instance via start(), the threads should run in parallel. (Thread 1 may get a small head start since it is kicked off first from the parent thread, but I'm going to guess that it does not matter in this case.)

Here's a working example that shows where threads should be working in parallel:

import sys
import threading

# Using sys.stdout.write() instead of print; it seems nicer for
# demoing threads in CPython :)

class Fizz(threading.Thread):
    def run(self):
        for i in xrange(10):
            sys.stdout.write("fizz\n")

class Buzz(threading.Thread):
    def run(self):
        for i in xrange(10):
            sys.stdout.write("buzz\n")

fizz = Fizz()
buzz = Buzz()
fizz.start()
buzz.start()

And here's what my output looks like:

C:\Users\Vultaire>test.py
fizz
fizz
fizz
fizz
fizz
buzz
buzz
buzz
buzz
fizz
buzz
fizz
fizz
buzz
fizz
fizz
buzz
buzz
buzz
buzz

The threads in your example appear to be started in this way, so they should be running in parallel. I'm guessing the problem is somewhere else? Or perhaps the threads are running in parallel and just didn't seem like it? (Please provide a more complete code example if you need further help! :))

Vultaire
  • 319
  • 3
  • 16
0

Multi-Threading in Python is bit tricky to achieve. You should have look at this.

Look at this

What is a global interpreter lock (GIL)?

PYTHON THREADS AND THE GLOBAL INTERPRETER LOCK

Community
  • 1
  • 1
New_User123
  • 104
  • 11
  • Link-only answers are *not* answer. Please *at least* copy a summary of the contents from the links, otherwise when the link will break your answer will be completely useless. – Bakuriu Feb 22 '14 at 13:26
0

From this, maybe it is working in parallel but the time for second thread to start then first thread terminated. You can try add sleep time in your functions so as to simulate the slowness of IO, as in this example

import threading
from time import sleep

def something():
    for i in xrange(10):
        sleep(0.01)
        print "Hello"

def my_thing():
    for i in xrange(10):
        sleep(0.01)
        print "world"   

threading.Thread(target=something).start()
threading.Thread(target=my_thing).start()
Community
  • 1
  • 1
kiriloff
  • 25,609
  • 37
  • 148
  • 229