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实现SMTP发送邮件详细教程
Mar 02 Python
HTML中使用python屏蔽一些基本功能的方法
Jul 07 Python
Python入门必须知道的11个知识点
Mar 21 Python
Pycharm 设置自定义背景颜色的图文教程
May 23 Python
深入解析python中的实例方法、类方法和静态方法
Mar 11 Python
Django集成搜索引擎Elasticserach的方法示例
Jun 04 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
Jan 08 Python
Python列表操作方法详解
Feb 09 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例
Mar 06 Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
Mar 30 Python
Python join()函数原理及使用方法
Nov 14 Python
手把手教你实现PyTorch的MNIST数据集
Jun 28 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脚本的10个技巧(7)
2006/10/09 PHP
Session的工作方式
2006/10/09 PHP
黑夜路人出的几道php笔试题
2009/08/04 PHP
php GeoIP的使用教程
2011/03/09 PHP
PHP中几个常用的魔术常量
2012/02/23 PHP
php实现可用于mysql,mssql,pg数据库操作类
2014/12/13 PHP
PHP实现XML与数据格式进行转换类实例
2015/07/29 PHP
Symfony2之session与cookie用法小结
2016/03/18 PHP
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
分享纯手写漂亮的表单验证
2015/11/19 Javascript
javascript中checkbox使用方法实例演示
2015/11/19 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
深入浅析JS的数组遍历方法(推荐)
2016/06/15 Javascript
JS 数字转换为大写金额的简单实例
2016/08/04 Javascript
Angular 应用技巧总结
2016/09/14 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
2016/09/15 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
vue中使用微信公众号js-sdk踩坑记录
2019/03/29 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
微信小程序服务器日期格式化问题
2020/01/07 Javascript
python连接mysql数据库示例(做增删改操作)
2013/12/31 Python
Python字符串格式化输出方法分析
2016/04/13 Python
numpy中索引和切片详解
2017/12/15 Python
Python实现bilibili时间长度查询的示例代码
2020/01/14 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
2020/08/07 Python
CSS3字体效果的设置方法小结
2016/06/13 HTML / CSS
五个2015 年最佳HTML5 框架
2015/11/11 HTML / CSS
英国50岁以上人群的交友网站:Ourtime
2018/03/28 全球购物
北卡罗来纳州豪华家具和家居装饰店:Carolina Rustica
2018/10/30 全球购物
巴西网上药店:Drogaria Araujo
2021/01/06 全球购物
香港百佳网上超级市场:PARKNSHOP.com
2020/06/10 全球购物
《地震中的父与子》教学反思
2014/04/10 职场文书
建筑安全生产责任书
2014/07/22 职场文书
2016春季运动会前导词
2015/11/25 职场文书
企业文化学习心得体会
2016/01/21 职场文书