python子线程退出及线程退出控制的代码


Posted in Python onOctober 16, 2019

下面通过代码给大家介绍python子线程退出问题,具体内容如下所示:

def thread_func():
  while True:
      #do something
      #do something
      #do something
t=threading.Thread(target = thread_func)
t.start()
# main thread do something
# main thread do something
# main thread do something

跑起来是没有问题的,但是使用ctrl + c中断的时候出问题了,主线程退出了,但子线程仍然运行。

于是在主线程增加了信号处理的代码,收到sigint时改变子线程循环条件

loop = True
def thread_func():
  while loop:
      #do something
      #do something
      #do something
t=threading.Thread(target = thread_func)
t.start()
# ctrl+c时,改变loop为False
def handler(signum, frame):
  global loop
  loop = False
  t.join()
  exit(0)
signal(SIGINT, handler)
# main thread do something
# main thread do something
# main thread do something

这样ctrl+c就可以退出了,但是疑惑的是,主线程退出进程不会退出吗?

知识点扩展Python线程退出控制

ctypes模块控制线程退出

Python中threading模块并没有设计线程退出的机制,原因是不正常的线程退出可能会引发意想不到的后果。

例如:

线程正在持有一个必须正确释放的关键资源,锁。

线程创建的子线程,同时也将被杀掉。

管理自己的线程,最好的处理方式是拥有一个请求退出标志,这样每个线程依据一定的时间间隔检查规则,看是不是需要退出。

例如下面的代码:

import threading
class StoppableThread(threading.Thread):
  """Thread class with a stop() method. The thread itself has to check
  regularly for the stopped() condition."""

  def __init__(self):
    super(StoppableThread, self).__init__()
    self._stop_event = threading.Event()

  def stop(self):
    self._stop_event.set()

  def stopped(self):
    return self._stop_event.is_set()

这段代码里面,线程应该定期检查停止标志,在退出的时候,可以调用stop()函数,并且使用join()函数来等待线程的退出。

然而,可能会出现确实想要杀掉线程的情况,例如你正在封装一个外部库,它会忙于长时间调用,而你想中断它。

Python线程可以抛出异常来结束:

传参分别是线程id号和退出标识

def _async_raise(tid, exctype):
  '''Raises an exception in the threads with id tid'''
  if not inspect.isclass(exctype):
    raise TypeError("Only types can be raised (not instances)")
  res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
                         ctypes.py_object(exctype))
  if res == 0:
    raise ValueError("invalid thread id")
  elif res != 1:
    # "if it returns a number greater than one, you're in trouble,
    # and you should call it again with exc=NULL to revert the effect"
    ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
    raise SystemError("PyThreadState_SetAsyncExc failed")

如果线程在python解释器外运行时,它将不会捕获中断,即抛出异常后,不能对线程进行中断。

简化后,以上代码可以应用在实际使用中来进行线程中断,例如检测到线程运行时常超过本身可以忍受的范围。

def _async_raise(tid, exctype):
  """raises the exception, performs cleanup if needed"""
  tid = ctypes.c_long(tid)
  if not inspect.isclass(exctype):
    exctype = type(exctype)
  res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
  if res == 0:
    raise ValueError("invalid thread id")
  elif res != 1:
    # """if it returns a number greater than one, you're in trouble,
    # and you should call it again with exc=NULL to revert the effect"""
    ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
    raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
  _async_raise(thread.ident, SystemExit)

总结

以上所述是小编给大家介绍的python子线程退出及线程退出控制的代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
详谈python read readline readlines的区别
Sep 22 Python
python判断列表的连续数字范围并分块的方法
Nov 16 Python
200行python代码实现2048游戏
Jul 17 Python
django 基于中间件实现限制ip频繁访问过程详解
Jul 30 Python
python使用writerows写csv文件产生多余空行的处理方法
Aug 01 Python
Python 获取numpy.array索引值的实例
Dec 06 Python
pytorch实现建立自己的数据集(以mnist为例)
Jan 18 Python
python梯度下降算法的实现
Feb 24 Python
python os模块在系统管理中的应用
Jun 22 Python
python-地图可视化组件folium的操作
Dec 14 Python
python Matplotlib基础--如何添加文本和标注
Jan 26 Python
python编程的核心知识点总结
Feb 08 Python
python Pillow图像处理方法汇总
Oct 16 #Python
win10环境下配置vscode python开发环境的教程详解
Oct 16 #Python
500行代码使用python写个微信小游戏飞机大战游戏
Oct 16 #Python
python提取xml里面的链接源码详解
Oct 15 #Python
python yield关键词案例测试
Oct 15 #Python
python 发送json数据操作实例分析
Oct 15 #Python
30秒学会30个超实用Python代码片段【收藏版】
Oct 15 #Python
You might like
PHP 彩色文字实现代码
2009/06/29 PHP
检查url链接是否已经有参数的php代码 添加 ? 或 &
2010/02/09 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
php实现简单的语法高亮函数实例分析
2015/04/27 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
thinkPHP下的widget扩展用法实例分析
2015/12/26 PHP
php fseek函数读取大文件两种方法
2016/10/12 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
Javascript实现CheckBox的全选与取消全选的代码
2010/07/20 Javascript
js实现addClass,removeClass,hasClass的函数代码
2011/07/13 Javascript
深入理解JavaScript系列(4) 立即调用的函数表达式
2012/01/15 Javascript
可选择和输入的下拉列表框示例
2013/11/05 Javascript
NodeJS学习笔记之(Url,QueryString,Path)模块
2015/01/13 NodeJs
JS实现的自定义右键菜单实例二则
2015/09/01 Javascript
BootStrap智能表单实战系列(九)表单图片上传的支持
2016/06/13 Javascript
JQuery遍历元素的后代和同胞实现方法
2016/09/18 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
详解如何快速配置webpack多入口脚手架
2018/12/28 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
vue组件开发之tab切换组件使用详解
2020/08/21 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
python模拟表单提交登录图书馆
2018/04/27 Python
python re模块的高级用法详解
2018/06/06 Python
利用Python将文本中的中英文分离方法
2018/10/31 Python
全球领先的美容用品专卖店:Beauty Plus Salon
2018/09/04 全球购物
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
Nike瑞士官网:Nike CH
2021/01/18 全球购物
咖啡书吧创业计划书
2014/01/13 职场文书
充分就业社区汇报材料
2014/05/07 职场文书
小学班主任培训方案
2014/06/04 职场文书
节约用电标语
2014/06/17 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL
MATLAB 全景图切割及盒图显示的实现步骤
2021/05/14 Python
安装配置mysql及Navicat prenium的详细流程
2021/06/10 MySQL