Python线程:使线程函数从外部信号返回

时间:2016-10-07 16:06:36

标签: python multithreading time

有人可以指出这段代码有什么问题。我试图通过变量标志返回线程,我想在我的主线程中控制它。

test27.py

Using version ^5.2 for laravelcollective/iron-queue
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- laravelcollective/iron-queue v5.2.2 requires iron-io/iron_mq ~2.0 -> satisfiable by iron-io/iron_mq[2.0.0, 2.x-dev] but these conflict with your requirements or m
inimum-stability
- laravelcollective/iron-queue v5.2.1 requires iron-io/iron_mq ~2.0 -> satisfiable by iron-io/iron_mq[2.0.0, 2.x-dev] but these conflict with your requirements or m
inimum-stability
- laravelcollective/iron-queue v5.2 requires iron-io/iron_mq ~2.0 -> satisfiable by iron-io/iron_mq[2.0.0, 2.x-dev] but these conflict with your requirements or min
imum-stability
- Conclusion: remove laravel/framework v5.3.17
- Conclusion: don't install laravel/framework v5.3.17
- laravelcollective/iron-queue v5.2.3 requires illuminate/queue 5.2.* -> satisfiable by illuminate/queue[v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.2.25, v5.2.26, v5.2.2
7, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7].
- laravelcollective/iron-queue v5.2.4 requires illuminate/queue 5.2.* -> satisfiable by illuminate/queue[v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.2.25, v5.2.26, v5.2.2
7, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7].
- don't install illuminate/queue v5.2.0|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.19|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.21|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.24|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.25|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.26|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.27|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.28|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.31|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.32|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.37|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.43|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.45|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.6|don't install laravel/framework v5.3.17
- don't install illuminate/queue v5.2.7|don't install laravel/framework v5.3.17
- Installation request for laravel/framework == 5.3.17.0 -> satisfiable by laravel/framework[v5.3.17].
- Installation request for laravelcollective/iron-queue ^5.2 -> satisfiable by laravelcollective/iron-queue[v5.2, v5.2.1, v5.2.2, v5.2.3, v5.2.4].

test28.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()

2 个答案:

答案 0 :(得分:0)

不应在线程中跟踪常规变量。这样做是为了防止竞争条件。您必须使用线程安全的构造来在线程之间进行通信。对于简单的标志,请使用threading.Event。此外,您无法通过线程对象访问本地变量flag。它是本地的,只能从范围中看到。您必须使用全局变量,如下面的示例所示,或者在调用线程之前创建一个Object并使用成员变量。

from threading import Event
flag = Event()

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

主线程:

sleep(5)
flag.set()

P.S。:我刚刚注意到你试图在线程中使用lock(),但未能在主线程中使用它。对于一个简单的标志,请使用Event。对于lock(),您需要锁定这两个部分并降低死锁风险。

答案 1 :(得分:0)

Thread类可以使用target参数进行实例化。然后你给它一个应该在新线程中运行的函数。这是一个启动简单线程的便捷方式,但是为了更多控制,通常更容易拥有一个继承自Thread的类,该类具有其他成员变量,例如用于中止的flag

例如:

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)

然后,要启动该主题,请致电start(),然后停止调用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
>>>