python 多线程使用

文章描述了一个名为classHandlerHostsInfoMulti的类,通过使用多线程和线程安全的方法,如锁和队列,对一批机器信息进行高效并发处理。它创建线程池,将主机信息分块,确保在非线程安全的数据结构(如字典和列表)中进行操作时保持数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多线程处理一批机器信息

    
class HandlerHostsInfoMulti:
    # 初始化host_obj字典,用于存储所有主机信息
    # 创建一个锁
    lock = threading.Lock()
    thread_num = 20
    res_map = {}
    res_list = []
    res_dict = {}

    @classmethod
    def create_multi_res_list(cls):
        for i in range(cls.thread_num):
            cls.res_map[i] = {}

    @classmethod
    def add_to_res_map(cls, i, host_name, value):
        cls.res_map[i][host_name] = value

    @classmethod
    def merge_res_map(cls):
        for value in cls.res_map.values():
            cls.res_dict.update(value)

    @classmethod
    def chunk_list(cls, lst, n):
        """Yield successive n-sized chunks from lst.√"""
        # 将host列表分成五部分
        step = len(lst) // n
        print("步长:", step)
        for i in range(0, len(lst), step):
            print("i=={},range:{}".format(i, lst[i : i + step]))
            yield lst[i : i + step]

    @classmethod
    def update_host_info(cls, hosts, thread_index):
        for host in hosts:
            host_obj = {}
            idc = host.get("idc")
            tag_info = host.get("tag_info", [])
            tags_name = ",".join([item.get("name") for item in tag_info if tag_info])
            hostname = host.get("hostname")
            host_obj.update(hostInfoObj(hostname).get_host_info_json(cls.get_runtime_mgs))
            host_obj.update({"idc": idc})
            host_obj.update({"tags": tags_name})
            # cls.append_to_list(host_obj)
            cls.add_to_res_map(thread_index, host_obj)

 # 创建线程函数
    @classmethod
    def worker(cls, q, thread_index):
        while not q.empty():
            hosts = q.get()
            # print("线程【{}】的hosts{}".format(thread_index,hosts))
            cls.update_host_info_dict(hosts, thread_index)
            q.task_done()


    @classmethod
    def multi_handler(cls, hosts):
        cls.create_multi_res_list()
        # 创建队列
        q = Queue()
        # 划分host列表并放入队列
        if len(hosts) <= 10:
            cls.thread_num = len(hosts)
        elif len(hosts) < 100 and len(hosts) > 10:
            cls.thread_num = 4
        else:
            cls.thread_num = 20
        for chunk in cls.chunk_list(hosts, cls.thread_num):
            q.put(chunk)

        # 创建多个线程
        threads = []
        for thread_index in range(cls.thread_num):
            t = threading.Thread(target=cls.worker, args=(q, thread_index))
            t.start()
            threads.append(t)

            # 等待所有任务完成
        q.join()
        # 返回host_obj列表
        cls.merge_res_map()
        return cls.res_dict
    #
    @classmethod
    def update_host_info_dict(cls, hosts, thread_index):
        for host in hosts:
            host_obj = {}
            host_name = host.get("host_name", "")
            if host_name:
                host_obj.update(hostInfoObj(host_name).get_host_info_json())
                cls.add_to_res_map(thread_index, host_name, host_obj)

    @classmethod
    def runtime_info_main_handler(cls, hosts):
        return cls.multi_handler(hosts)
 

根据线程数量,先使用chunk_list()将hosts数组分成几份,每个线程单独使用一份hosts切片对象。

create_multi_res_list()生成保存数据,不同线程使用map的不同key对应的value空间保存值,注意:dict是虽然不是线程安全的。但是可以使用不同的线程index,指定线程使用的空间。

list也不是线程安全的,若是需要使用的话,需要threading lock

import threading
  
  lock = threading.Lock()

@classmethod
    def append_to_list(cls,item):
        # 获取锁
        cls.lock.acquire()
        try:
            # 在锁的保护下向列表添加元素
            cls.host_resp.append(item)
        finally:
            # 释放锁
            cls.lock.release()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值