【小菜虫学习笔记-Python多线程自检测脚本】


前言

由于本人在实际的工作中运行多线程脚本,线程数经常越跑越少,于是通过阅读官方文档想到了这种解决方案。基于threading的一种多线程监控脚本。


一、threading的官方简介

  • 在 CPython 中,由于存在 全局解释器锁,同一时刻只有一个线程可以执行 Python 代码(虽然某些性能导向的库可能会去除此限制)。 如果你想让你的应用更好地利用多核心计算机的计算资源,推荐你使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。 但是,如果你想要同时运行多个 I/O 密集型任务,则多线程仍然是一个合适的模型。
  • 官方文档:threading — 基于线程的并行

二、使用步骤

1.常用方法

代码如下(示例):

import threading
import time


def run(index):
    print(f'我是第 {index} 个线程, name: {thread.name}')
    time.sleep(index)


for i in range(5):
    thread = threading.Thread(target=run, args=(i,), name=f'name_{i}')
    thread.start()

2.实际的应用场景需求

  • 消费者需要不停的向生产者请求数据
  • 采用多线程的方式提高运行效率
  • 检测每个线程的运行状态,如果线程结束或者是因异常终止,就拉起终止的线程数,保证始终有指定的线程数在运行

3.方案实现

  • 查阅官方文档中的介绍发现 enumerate 方法刚好满足需求
threading.enumerate()
返回当前所有存活的 Thread 对象的列表。 该列表包括守护线程以及 current_thread() 创建的空线程。 它不包括已终结的和尚未开始的线程。 但是,主线程将总是结果的一部分,即使是在已终结的时候。
  • 通过一个简单的实例,可以发现 enumerate方法返回的是一个列表,并且包含了线程的名称

运行结果

  • 最终实现
import re
import time
import threading


def run(index):
    print(f'我是第 {index} 个线程, name: {thread.name}')
    time.sleep(index)


def detection_of_thread():
    while True:
        thread_list = threading.enumerate()
        # 用来存储还在运行的线程的索引
        viable_thread_list = []
        for _thread in thread_list:
            if re.findall(r'name_(\d*)', _thread.getName()):
                # 将还在运行的线程的索引加入打列表中
                viable_thread_list.append(re.findall(r'name_(\d*)', _thread.getName())[0])
            else:
                pass

        #  通过判断列表中的索引数是否与指定要开始的线程数相等,相等则说明线程都在运行中
        if len(viable_thread_list) == thread_num:
            pass

        else:
            for index in range(1, thread_num+1):
                # 通过遍历来判断哪个线程已经运行结束, 然后再次启动
                if index not in viable_thread_list:
                    print(f'我是第{index}个线程, 我暴毙了,被抬进了急症室')
                    death = threading.Thread(target=run, args=(index,), name=f'name_{index}')
                    death.start()
                    print(f'我是第{index}个线程, 我又活过来了')

        time.sleep(1)


if __name__ == '__main__':

    thread_num = 5
    for i in range(1, thread_num+1):
        thread = threading.Thread(target=run, args=(i,), name=f'name_{i}')
        thread.start()

    # 启动检测的线程
    detection = threading.Thread(target=detection_of_thread, name='detection')
    detection.start()


总结

多多阅读官方文档

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值