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实现的百度贴吧网络爬虫实例
Apr 17 Python
Python性能提升之延迟初始化
Dec 04 Python
python 捕获 shell/bash 脚本的输出结果实例
Jan 04 Python
Python 专题三 字符串的基础知识
Mar 19 Python
python素数筛选法浅析
Mar 19 Python
python生成不重复随机数和对list乱序的解决方法
Apr 09 Python
python实现判断一个字符串是否是合法IP地址的示例
Jun 04 Python
Django 多语言教程的实现(i18n)
Jul 07 Python
python中time库的实例使用方法
Oct 31 Python
pytorch torchvision.ImageFolder的用法介绍
Feb 20 Python
conda安装tensorflow和conda常用命令小结
Feb 20 Python
Python3中最常用的5种线程锁实例总结
Jul 07 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函数计算中英文字符串长度的方法
2014/11/11 PHP
PHP封装的数据库保存session功能类
2016/07/11 PHP
PHP  Yii清理缓存的实现方法
2016/11/10 PHP
ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
2018/07/30 PHP
PHP工厂模式、单例模式与注册树模式实例详解
2019/06/03 PHP
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
js实现通用的微信分享组件示例
2014/03/10 Javascript
无刷新预览所选择的图片示例代码
2014/04/02 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
javascript实现一个数值加法函数
2015/06/26 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
Vue中util的工具函数实例详解
2019/07/08 Javascript
vue使用混入定义全局变量、函数、筛选器的实例代码
2019/07/29 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
design vue 表格开启列排序的操作
2020/10/28 Javascript
夯基础之手撕javascript继承详解
2020/11/09 Javascript
[01:40]2014DOTA2国际邀请赛 三冰SOLO赛后采访恶搞
2014/07/09 DOTA
[05:43]VG.R战队教练Mikasa专访:为目标从未停止战斗
2016/08/02 DOTA
[58:57]2018DOTA2亚洲邀请赛3月29日小组赛B组 Effect VS VGJ.T
2018/03/30 DOTA
python中requests爬去网页内容出现乱码问题解决方法介绍
2017/10/25 Python
使用python 3实现发送邮件功能
2018/06/15 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
pytorch标签转onehot形式实例
2020/01/02 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
使用Django搭建网站实现商品分页功能
2020/05/22 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
.net工程师笔试题
2012/06/09 面试题
个人剖析材料及整改措施
2014/10/07 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
党的群众路线教育实践活动个人整改方案
2014/10/25 职场文书
教师年终个人总结
2015/02/11 职场文书
网络研修随笔感言
2015/11/18 职场文书
五年级作文之想象作文
2019/10/30 职场文书