猿问

如何中断否则超时的线程?

我需要写一个线程:

  • 运行n秒,然后执行 A(并退出)

  • 除非它的父级告诉它提前停止,在这种情况下它会执行 B(并退出)

我写了一些有效但非常复杂的东西(我相信)。它(错误)使用 aLock()作为标志:

import threading

import time


def countdown(lock):

    t = 0

    while t < 10:

        t += 1

        print(t)

        try:

            lock.release()

        except RuntimeError:

            # was not told to die (= lock is not set)

            pass

        else:

            # the parent notified to kill by setting the lock

            print("child: the lock has been set, means I die before timeout")

            return

        time.sleep(1)


    # executed when timeouting

    print("child: I timeouted on my own")

    return


lock = threading.Lock()

# with timeout

threading.Thread(target=countdown, args=(lock,)).start()

print("parent: sleeping 12 seconds, the thread should timeout in the meantime")

time.sleep(12)


lock = threading.Lock()

# without timeout

threading.Thread(target=countdown, args=(lock,)).start()

print("parent: sleeping 5 seconds, and then setting the flag")

time.sleep(5)

lock.acquire()

print("the counter should exit prematurely while I continue sleeping")

time.sleep(5)

它工作正常(我不关心时间的细微变化 - 在这种情况下是 6 秒 vs 5 秒,因为主线程和生成的线程共同运行):


1

parent: sleeping 12 seconds, the thread should timeout in the meantime

2

3

4

5

6

7

8

9

10

child: I timeouted on my own

1

parent: sleeping 5 seconds, and then setting the flag

2

3

4

5

the counter should exit prematurely while I continue sleeping

6

child: the lock has been set, means I die before timeout

正如我所提到的,这个解决方案对我来说看起来非常复杂。


是否有更 Pythonic 的构造可以运行超时线程,可被其父线程中断?


慕仙森
浏览 91回答 1
1回答

皈依舞

如果额外的线程仅用于倒计时,同时不执行任何其他功能,则该threading.Timer()对象就是为此而创建的。如果需要,可以使用该.cancel()方法提前取消计时器。更多信息可以在官方文档中找到。从问题中重写示例(稍作修改)使代码看起来像:import threadingimport time# with timeoutt = threading.Timer(10.0, lambda: print("I timed out"))t.start()print("Parent: Sleeping 12 seconds, the thread should timeout in the meantime")time.sleep(12)print("Done sleeping")# without timeoutt = threading.Timer(10.0, lambda: print("I timed out"))t.start()print("Parent: Sleeping 6 seconds, and then cancel timers")time.sleep(6)t.cancel()print("The counter is canceled while I continue sleeping")time.sleep(6)print("Done sleeping")
随时随地看视频慕课网APP

相关分类

Python
我要回答