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进阶-函数默认参数(详解)
May 18 Python
人工智能最火编程语言 Python大战Java!
Nov 13 Python
基于python OpenCV实现动态人脸检测
May 25 Python
Python标准库shutil用法实例详解
Aug 13 Python
Python使用gRPC传输协议教程
Oct 16 Python
python 堆和优先队列的使用详解
Mar 05 Python
浅谈Pytorch中的torch.gather函数的含义
Aug 18 Python
python实现树的深度优先遍历与广度优先遍历详解
Oct 26 Python
4行Python代码生成图像验证码(2种)
Apr 07 Python
学会python自动收发邮件 代替你问候女友
May 20 Python
Python如何输出警告信息
Jul 30 Python
python 逆向爬虫正确调用 JAR 加密逻辑
Jan 12 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实现删除字符串中任何字符的函数
2015/08/11 PHP
Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
2016/03/21 PHP
表单提交验证类
2006/07/14 Javascript
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
Javascript 函数parseInt()转换时出现bug问题
2014/05/20 Javascript
js数组依据下标删除元素
2015/04/14 Javascript
js实现两点之间画线的方法
2015/05/12 Javascript
简单谈谈javascript中this的隐式绑定
2016/02/22 Javascript
ES6解构赋值的功能与用途实例分析
2017/10/31 Javascript
详解React 在服务端渲染的实现
2017/11/16 Javascript
bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)
2017/11/17 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
Node.js中的child_process模块详解
2018/06/08 Javascript
微信小程序实现自定义picker选择器弹窗内容
2020/05/26 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
2019/04/17 Javascript
基于vue实现一个神奇的动态按钮效果
2019/05/15 Javascript
Python中文件遍历的两种方法
2014/06/16 Python
Python中使用tarfile压缩、解压tar归档文件示例
2015/04/05 Python
Python3学习笔记之列表方法示例详解
2017/10/06 Python
python numpy 部分排序 寻找最大的前几个数的方法
2018/06/27 Python
python2和python3应该学哪个(python3.6与python3.7的选择)
2019/10/01 Python
Python关于反射的实例代码分享
2020/02/20 Python
python爬虫容易学吗
2020/06/02 Python
Python xmltodict模块安装及代码实例
2020/10/05 Python
美国高品质个性化珠宝销售网站:Jewlr
2018/05/03 全球购物
Calphalon美国官网:美国顶级锅具品牌
2020/02/05 全球购物
前台接待岗位职责
2013/12/03 职场文书
班组长安全生产职责
2013/12/16 职场文书
趣味游戏活动方案
2014/02/07 职场文书
养成教育经验材料
2014/05/26 职场文书
动物科学专业求职信
2014/07/27 职场文书
孔子观后感
2015/06/08 职场文书
银行岗位培训心得体会
2016/01/09 职场文书
Go语言 go程释放操作(退出/销毁)
2021/04/30 Golang
微信小程序 WeUI扩展组件库的入门教程
2022/04/21 Javascript