Stop the thread from inside the target function?
<p>Is there a way that I can stop the thread after few seconds (INTERNALLY)</p>

<pre><code>t1 = Thread(target=call_script1, args=())
t2 = Thread(target=call_script2, args=())
t3 = Thread(target=call_script3, args=())

t1.start()
t2.start()
t3.start()

t1.join()
t2.join()
t3.join()
</code></pre>

<p>The Main program waits until thread returns. I would like to know if there is a way - when I spawn a thread - say t2, it targets a function - call_script2. Lets say that function takes like 5 seconds to run completely. I would like to know if I can return the thread say like after 3 seconds.</p>

<p>The ability of the thread to return after 3 seconds should be inside the call_script2 function. I believe having stop_event.wait(3) in the main thread does not work.</p>

<p>call_script2 function looks something like this.</p>

<pre><code>def InterfaceThread2():
    a = 1;
    d = 2
    i = 1
    while i ==1:
        #ser = serial.Serial(3, 115200)
        if ser.isOpen():
            ser.write('\x5A\x03\x02\x00\x02\x07')

            a = ser.read(7) #### THIS COMMAND WAITS UNTIL IT RECEIVES DATA FROM MCU
            ## This usually happens in 100ms in theory. If it is taking like more than 100ms -for safety say I will wait for three seconds and if it did not respond back
            ## I want to stop the thread and popup an error message.

        # Tell the GUI about the Information
        wx.CallAfter(pub.sendMessage, "APP_EVENT2", arg1 = a, arg2 = d)
        print "hello"

        time.sleep(1)
        i = i+1
</code></pre>

<p>I think you can get the behavior you want by using the <code>timeout</code> parameter available on the <code>serial.Serial()</code> constructor. Additionally, you'll need to protect your interactions with the <code>Serial</code> instance with a <code>threading.Lock()</code>, so that your threads don't step on each other as they read/write data:</p>

<pre><code>ser = serial.Serial(..., timeout=3, ...)
lock = Threading.Lock()

def call_script1():
    a = 1
    d = 2
    i = 1
    while i == 1:  # Lock is acquired here
        with lock:
            if ser.isOpen():
                ser.write('\x5A\x03\x02\x00\x02\x07')
                a = ser.read(7)
                if len(a) != 7:
                    # We didn't get all the bytes we wanted, a timeout
                    # must have occurred.
                    print("Only read {} bytes!".format(len(a)))
                    # Maybe exit or throw an exception?

        # Lock is released here.
        # Tell the GUI about the Information
        wx.CallAfter(pub.sendMessage, "APP_EVENT2", arg1 = a, arg2 = d)
        print "hello"

        time.sleep(1)
        i = i+1

def call_script2():
    while i == 1:
        with lock:
            if ser.isOpen():
                # Do whatever

def call_script3():
    while i == 1:
        with lock:
            if ser.isOpen():
                # Do whatever

t1 = Thread(target=call_script1, args=())
t2 = Thread(target=call_script2, args=())
t3 = Thread(target=call_script3, args=())

t1.start()
t2.start()
t3.start()

t1.join()
t2.join()
t3.join()
</code></pre>

python multithreading