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实现的登录和操作开心网脚本分享
Jul 09 Python
在Python中使用zlib模块进行数据压缩的教程
Jun 26 Python
Python实现将Excel转换成xml的方法示例
Aug 25 Python
解决python测试opencv时imread导致的错误问题
Jan 26 Python
Django 实现admin后台显示图片缩略图的例子
Jul 28 Python
python matplotlib imshow热图坐标替换/映射实例
Mar 14 Python
python中threading开启关闭线程操作
May 02 Python
使用Keras预训练模型ResNet50进行图像分类方式
May 23 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
Jun 18 Python
解决keras GAN训练是loss不发生变化,accuracy一直为0.5的问题
Jul 02 Python
Python中seaborn库之countplot的数据可视化使用
Jun 11 Python
pytest实现多进程与多线程运行超好用的插件
Jul 15 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
discuz的php防止sql注入函数
2011/01/17 PHP
PHP 无限分类三种方式 非函数的递归调用!
2011/08/26 PHP
php计算一个文件大小的方法
2015/03/30 PHP
dojo随手记 gird组件引用
2011/02/24 Javascript
javascript学习笔记(七) js函数介绍
2012/06/19 Javascript
用表格输出1-1000之间的数字实现代码(附特效)
2013/04/21 Javascript
jquery.ajax之beforeSend方法使用介绍
2014/12/08 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
jquery实现页面关键词高亮显示的方法
2015/03/12 Javascript
js实现缓冲运动效果的方法
2015/04/10 Javascript
jQuery基础知识点总结(DOM操作)
2016/06/01 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
JS瀑布流实现方法实例分析
2016/12/19 Javascript
WebSocket实现简单客服聊天系统
2017/05/12 Javascript
vue中使用微信公众号js-sdk踩坑记录
2019/03/29 Javascript
使用vue实现各类弹出框组件
2019/07/03 Javascript
js刷新页面location.reload()用法详解
2019/12/09 Javascript
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
2020/08/06 Javascript
Vue切换Tab动态渲染组件的操作
2020/09/21 Javascript
[40:57]TI4 循环赛第二日 iG vs EG
2014/07/11 DOTA
通过python将大量文件按修改时间分类的方法
2018/10/17 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
python join方法使用详解
2019/07/30 Python
python实现邮件发送功能
2019/08/10 Python
捷克厨房用品购物网站:Tescoma
2018/07/13 全球购物
标记环介质访问控制协议
2016/03/27 面试题
解释一下钝化(Swap out)
2016/12/26 面试题
介绍一下Prototype的$()函数,$F()函数,$A()函数都是什么作用?
2014/03/05 面试题
劳资专员岗位职责
2013/12/27 职场文书
大学生职业生涯规划范文——找准自我,定位人生
2014/01/23 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
库房保管员岗位职责
2014/04/07 职场文书
医学生求职信
2014/07/01 职场文书
团队拓展活动方案
2014/08/28 职场文书
开学第一周总结
2015/07/16 职场文书
小学运动会开幕词
2016/03/04 职场文书