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>The <a href="https://docs.python.org/3/library/threading.html#threading.Thread" rel="nofollow"><code>Thread.join</code></a> method has an optional <code>timeout</code> parameter.</p>

<pre><code># block until thread ``t`` completes, or just wait 3 seconds
t.join(3)
</code></pre>

<p>If you want the target function to handle this logic of timing out, I suggest writing a wrapper to spawn a new thread, make the call, then join with a 3-second timeout.</p>

<pre><code>from threading import Thread
import time

def counter(limit):
    for i in range(limit):
        print(i)
        time.sleep(0.1)

timeout = 3
def wrapper(*args, **kwargs):
    t = Thread(target=counter, args=args, kwargs=kwargs)
    t.daemon = True
    t.start()
    t.join(timeout)

t = Thread(target=wrapper, args=(100,))
t.start()
t.join()
</code></pre>

<p>Note that this doesn't actually kill the subthread until the main process dies. Killing a thread without knowing what it's doing inside could cause all sorts of mess.</p>

<p>If you can change the code of the original functions, you can have them periodically poll to check if anyone wants them dead.</p>

<p>Edit: Looks like I somewhat misunderstood the question. It was more about how to use PySerial to share 1 open <code>Serial</code> object across 3 workers, with a timeout on reads from the serial port.</p>

python multithreading