Python Threading: Making the thread function retur

2019-09-16 02:20发布

Could anyone please point out whats wrong with this code. I am trying to return the thread through a variable flag, which I want to control in my main thread.

test27.py

import threading
import time

lock = threading.Lock()

def Read(x,y):
    flag = 1
    while True:
        lock.acquire()
        try:
            z = x+y; w = x-y
            print z*w
            time.sleep(1)
            if flag == 0:
                print "ABORTING"
                return
        finally:
            print " SINGLE run of thread executed"
            lock.release()

test28.py

import time, threading

from test27 import Read

print "Hello Welcome"
a = 2; b = 5
t = threading.Thread(target = Read, name = 'Example Thread', args = (a,b))
t.start()
time.sleep(5)
t.flag = 0 # This is not updating the flag variable in Read FUNCTION
t.join() # Because of the above command I am unable to wait until the thread finishes. It is blocking.
print "PROGRAM ENDED"

2条回答
放我归山
2楼-- · 2019-09-16 02:30

The Thread class can be instantiated with the target argument. Then you just give it a function which should be executed in a new thread. It is a convenient way to start a simple thread, but for more control it is usually easier to have a class inherited from Thread, which has additional member variables, like the flag for aborting.

For example:

import time
import threading

class MyThread(threading.Thread):
    def __init__(self, x, y):
        super().__init__()
        # or in Python 2:
        # super(MyThread, self).__init__()
        self.x = x
        self.y = y
        self._stop_requested = False

    def run(self):
        while not self._stop_requested:
            z = self.x + self.y
            w = self.x - self.y
            print (z * w)
            time.sleep(1)

    def stop(self, timeout=None):
        self._stop_requested = True
        self.join(timeout)

Then, to start the thread, call start() and then to stop it call stop():

>>> def run_thread_for_5_seconds():
...     t = MyThread(3, 4)
...     t.start()
...     time.sleep(5)
...     t.stop()
...
>>> run_thread_for_5_seconds()
-7
-7
-7
-7
-7
>>>
查看更多
唯我独甜
3楼-- · 2019-09-16 02:39

Regular variables should not be tracked in threads. This is done to prevent race condition. You must use thread-safe constructs to communicate between threads. For a simple flag use threading.Event. Also you cannot access local variable flag via thread object. It is local, and is only visible from scope. You must either use a global variable, as in my example below or create an Object before calling your thread and use a member variable.

from threading import Event
flag = Event()

def Read(x,y):
    global flag
    flag.clear()
    ...
    if flag.is_set():
        return

main thread:

sleep(5)
flag.set()

P.S.: I just noticed that you attempted to use lock() in the thread, but failed to use it in the main thread. For a simple flag go with Event. For a lock() you need to lock both parts and mitigate a risk of a deadlock.

查看更多
登录 后发表回答