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机器学习之神经网络实现
Oct 13 Python
python异常触发及自定义异常类解析
Aug 06 Python
详解python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
Aug 27 Python
Python Sympy计算梯度、散度和旋度的实例
Dec 06 Python
python groupby 函数 as_index详解
Dec 16 Python
tensorflow 获取所有variable或tensor的name示例
Jan 04 Python
Python多重继承之菱形继承的实例详解
Feb 12 Python
pyCharm 实现关闭代码检查
Jun 09 Python
如何用PyPy让你的Python代码运行得更快
Dec 02 Python
BeautifulSoup中find和find_all的使用详解
Dec 07 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
Python  序列化反序列化和异常处理的问题小结
Dec 24 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
杏林同学录(九)
2006/10/09 PHP
PHP连接SQLServer2005 的问题解决方法
2010/07/19 PHP
php下批量挂马和批量清马代码
2011/02/27 PHP
php 数据库字段复用的基本原理与示例
2011/07/22 PHP
逆序二维数组插入一元素的php代码
2012/06/08 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
2016/07/15 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
2019/05/06 PHP
php设计模式之工厂方法模式分析【星际争霸游戏案例】
2020/01/23 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
jQuery中before()方法用法实例
2014/12/25 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
利用jQuery异步上传文件的插件用法详解
2017/07/19 jQuery
微信小程序 上传头像的实例详解
2017/10/27 Javascript
node的process以及child_process模块学习笔记
2018/03/06 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
Python实现抓取网页并且解析的实例
2014/09/20 Python
Python数据结构之顺序表的实现代码示例
2017/11/15 Python
python 发送和接收ActiveMQ消息的实例
2019/01/30 Python
python删除文件夹下相同文件和无法打开的图片
2019/07/16 Python
Python进程Multiprocessing模块原理解析
2020/02/28 Python
基于Python生成个性二维码过程详解
2020/03/05 Python
通过实例简单了解python yield使用方法
2020/08/06 Python
python如何获得list或numpy数组中最大元素对应的索引
2020/11/16 Python
matplotlib bar()实现多组数据并列柱状图通用简便创建方法
2021/02/24 Python
一款利用html5和css3实现的3D立方体旋转效果教程
2016/04/26 HTML / CSS
Under Armour美国官网:美国知名高端功能性运动品牌
2016/09/05 全球购物
美国在线打印网站:Overnight Prints
2018/10/11 全球购物
大学生毕业自我评价范文分享
2013/11/07 职场文书
小学生爱国演讲稿
2014/04/25 职场文书
暑期培训班招生方案
2014/08/26 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
新党章的学习心得体会
2014/11/07 职场文书
2015年党员个人剖析材料
2014/12/18 职场文书
导游词之西安大清真寺
2019/12/17 职场文书