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实现手机通讯录搜索功能
Feb 22 Python
Python开发最牛逼的IDE——pycharm
Aug 01 Python
python将秒数转化为时间格式的实例
Sep 16 Python
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
Nov 29 Python
Python读取csv文件分隔符设置方法
Jan 14 Python
Python将json文件写入ES数据库的方法
Apr 10 Python
详解Django配置优化方法
Nov 18 Python
numpy ndarray 取出满足特定条件的某些行实例
Dec 05 Python
Python print不能立即打印的解决方式
Feb 19 Python
Jupyter Notebook打开任意文件夹操作
Apr 14 Python
Python中的 No Module named ***问题及解决
Jul 23 Python
Python sklearn分类决策树方法详解
Sep 23 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 常用类整理
2009/12/23 PHP
Codeigniter注册登录代码示例
2014/06/12 PHP
php使用百度ping服务代码实例
2014/06/19 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
PHP函数checkdnsrr用法详解(Windows平台用法)
2016/03/21 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
PHP按一定比例压缩图片的方法
2018/10/12 PHP
PHP 8新特性简介
2020/08/18 PHP
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
11个用于提高排版水平的基于jquery的文字效果插件
2012/09/14 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
ExtJS实现文件下载的方法实例
2013/11/09 Javascript
javascript自动恢复文本框点击清除后的默认文本
2016/01/12 Javascript
nodejs个人博客开发第三步 载入页面
2017/04/12 NodeJs
深入理解vue.js中$watch的oldvalue与newValue
2017/08/07 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
vue如何引入sass全局变量
2018/06/28 Javascript
微信小程序下拉框搜索功能的实现方法
2019/07/31 Javascript
JS实现灯泡开关特效
2020/03/30 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
Python中asyncio与aiohttp入门教程
2018/10/16 Python
Python面向对象之类的封装操作示例
2019/06/08 Python
对python中UDP,socket的使用详解
2019/08/22 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
python将音频进行变速的操作方法
2020/04/08 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
2020/06/01 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
澳大利亚Rockwear官网:女子瑜伽、健身和运动服
2021/01/26 全球购物
信息系统专业个人求职信范文
2013/12/07 职场文书
2015年学生资助工作总结
2015/05/25 职场文书
创新创业项目计划书该怎样写?
2019/08/13 职场文书
mysql5.7使用binlog 恢复数据的方法
2021/06/03 MySQL
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL