Python在子线程无线循环的过程中,如果直接ctrl+c结束程序的话,虽然程序可以结束,但是会导致子线程资源无法回收,一般情况不会有太大影响,但是使用TCP通信的时候,子线程是占用特定的端口的,在资源没有回收的情况下,再次启动程序就会报端口占用错误可以手动回收资源如下:

# 我的套接字的端口是8899
$ netstat -nap | grep
# 会显示进程号port
$ kill - port

所以参考https://blog.csdn.net/hp_cpp/article/details/83040162博主的方法如下强制结束子线程:

import inspect
import ctypes
from threading import Thread 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) def Receive():
while 1:
print(1)
time.sleep(0.1) def Send():
while 1:
print(2)
time.sleep(0.1) if __name__ == "__main__":
t1 = Thread(target=Receive)
t2 = Thread(target=Send)
t1.start()
t2.start()
stop_thread(t1)
stop_thread(t2)

以下是我的测试程序,结合signal方法,主线程一直循环,一旦检测到按下Ctrl+c,就会打印出'You pressed Ctrl+C!'这句话,并且调用上述方法结束两个无限循环的子线程,最后调用exit()方法优雅的结束整个程序

import inspect
import ctypes
import signal
import sys
import time
from threading import Thread 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) def signal_handler(signal, frame):
print('You pressed Ctrl+C!')
stop_thread(t1)
stop_thread(t2)
sys.exit() def Receive():
while 1:
print(1)
time.sleep(0.1) def Send():
while 1:
print(2)
time.sleep(0.1) if __name__ == "__main__":
t1 = Thread(target=Receive)
t2 = Thread(target=Send)
t1.start()
t2.start()
print(3)
while True:
signal.signal(signal.SIGINT, signal_handler)
print(4)
time.sleep(0.1)

Pytrhon结束死循环的子线程的更多相关文章

  1. python主线程与子线程的结束顺序

    引用自 主线程退出对子线程的影响--YuanLi 的一段话: 对于程序来说,如果主进程在子进程还未结束时就已经退出,那么Linux内核会将子进程的父进程ID改为1(也就是init进程),当子进程结束后 ...

  2. java 多线程 Thread.join子线程结束父线程再运行;join(long):等待超时毫秒数

    Join的使用 目的:当子线程运行结束后,父线程才能再继续运行 /** * @ClassName ThreadJoinExample * @projectName: object1 * @author ...

  3. C#主线程等待子线程运行结束

    佐左佑右 原文 C#主线程等待子线程运行结束 由于主程序中调用matlab的dll文件进行计算要用较长的时间,主界面会有很长时间的卡顿,造成的用户感受十分不好,因此我想在调用时,将调用放入子线程中,然 ...

  4. Java如何等待子线程执行结束

    工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...

  5. java主线程结束和子线程结束之间的关系

    (一)Main线程是个非守护线程,不能设置成守护线程. 这是因为,main线程是由java虚拟机在启动的时候创建的.main方法开始执行的时候,主线程已经创建好并在运行了.对于运行中的线程,调用Thr ...

  6. Java_如何等待子线程执行结束

    工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...

  7. iOS中安全结束 子线程 的方法

    一个典型的结束子线程的方法:   用 isFinished 检测子线程是否被完全kill掉 -(IBAction)btnBack:(id)sender { //释放内存 仅仅remove 并不会触发内 ...

  8. Java Thread.join()详解--父线程等待子线程结束后再结束

    目录(?)[+] 阅读目录 一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法   join是Th ...

  9. Java主线程如何等待子线程执行结束(转)

    工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...

随机推荐

  1. 前端面试题汇总(主要为 Vue)

    前端面试题汇总 1. 谈谈你对MVVM开发模式的理解 MVVM分为Model.View.ViewModel三者. 1)Model:代表数据模型,数据和业务逻辑都在Model层中定义: 2)View:代 ...

  2. vim模式下报错E37: No write since last change (add ! to override)

    故障现象: 使用vim修改文件报错,系统提示如下: E37: No write since last change (add ! to override) 故障原因: 文件为只读文件,无法修改. 解决 ...

  3. linux sudo 运行找不到java、python命令

    在Ubuntu环境中安装好Java环境后设置环境变量:在/etc/profile中设置好了JAVA_HOME变量并引入到PATH中, 由于Ubuntu默认是不以root用户登录的,这时echo $PA ...

  4. linux(centos7)设置tomcat开机启动

    1.在/etc/rc.d/rc.local中加入: #java environment export JAVA_HOME=/usr/java/jdk1.8.0_161 export CLASSPATH ...

  5. SpringBoot 2.x.x会拦截静态资源问题

    之前在看尚硅谷视频时,可谓是按照这老师的说法,一步一步按部就班,于是采坑了,在SpringBoot 2.x.x之前是不会对静态资源拦截的,但是现在已经普通使用2.x.x这个版本会对静态资源进行拦截.看 ...

  6. vue + ts @Prop boolean 问题

    假设btn组件有一prop属性radio,声明如下 @Prop({ default: false }) radio!: boolean; 在组件传递 <btn radio /> 此时的 r ...

  7. css 修改svg图标的颜色(不修改fill)

    给icon加样式 (利用原图标的阴影区域,同时将原图标移动超过之前父元素范围)filter: drop-shadow(red 80px 0);transform: translateX(-80px); ...

  8. Oracle数据泵远程导入数据

    查看现存镜像目录 select * from dba_directories; 创建镜像目录 create or replace directory my_dir as 'local_dir' ; 把 ...

  9. vue页面无操作10分钟内调转到登录页面

    https://blog.csdn.net/lbPro0412/article/details/83864454 页面在设定时间内无任何操作(鼠标的点击.滑动.路由的切换.是否请求接口等),跳转到登录 ...

  10. TCP 服务端接收数据解析工具类

    package com.ivchat.common.util; import java.io.BufferedReader;import java.io.IOException;import java ...