Python 多线程响应 ctrl+c 优雅退出的方式,代码如下,欢迎交流

2016-11-27 21:48:11 +08:00
 cdwyd

对优雅这个词敏感的话,请忽略

import time
import random
from threading import Thread

stop = False
threads_num = 20

todos = list(range(1000))
total = len(todos)

def test(name):
    while todos:
        todo = todos.pop()
        # print('{}获取到 todo-{}'.format(name, todo))
        sleep_time = random.randint(1, 5) / 10
        # print('{}休息{}秒'.format(name, sleep_time))
        time.sleep(sleep_time)
        if stop:
            print('{}收到结束信号正在处理'.format(name))
            break
    print('{}结束'.format(name))


if __name__ == '__main__':
    start_time = time.time()
    # 启动线程
    threads = []
    for i in range(threads_num):
        t = Thread(target = test, args = ('线程-{}'.format(i),))
        threads.append(t)
        t.start()
    
    # 响应 ctrl+c
    try:
        while todos:
            print('已完成{}中的{},还剩余{}'.format(total, total - len(todos), len(todos)))
            time.sleep(1)
    except KeyboardInterrupt as e:
        print('收到结束信号,正在处理')
        stop = True

    # 确认所有子线程结束
    for t in threads:
        t.join()
        
    print('所有子线程已结束')
    print('执行清理工作...')
    print('共计用时{}秒'.format(time.time() - start_time))
4509 次点击
所在节点    Python
7 条回复
darkbill
2016-11-27 23:57:37 +08:00
曾经试过类似的写法~~~
ryd994
2016-11-28 00:33:20 +08:00
子线程里也要响应 keyboard interrupt
或者使用 signal 模块
xiamx
2016-11-28 00:53:43 +08:00
很好的 标准做法
pright
2016-11-28 01:10:55 +08:00
楼主你可以试试把 time.sleep(sleep_time)里的 sleep_time 改成一个很大的值,再 ctrl+c ,试试是什么结果
thekoc
2016-11-28 09:41:43 +08:00
我之前也是这么做的,但是就像 @pright 所说, sleep_time 很大的时候直接阻塞在那里了
cdwyd
2016-11-28 09:49:52 +08:00
@pright
@thekoc
子线程运行时间太久会阻塞,响应会有延迟。我主要是写爬虫的时候这么用影响不算大。有其他的方法解决这个问题吗
thekoc
2016-11-28 11:01:31 +08:00
@cdwyd 后来我在 sleep 那里写了一个 while 循环,把时间切分成很小的原子时间,每一次循环都去判断一次,感觉比较丑陋……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/323676

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX