# 列表多线程处理

import sys
import threading
import queue



def 二次函数(函数, 线程id, 进程锁, 输入队列, 输出结果, 提示进度):
    def 进度条():
        total = len(输出结果)
        done = len(输出结果) - 输出结果.count(None)
        percent = done / total if total else 0

        bar_len = 40
        filled = int(bar_len * percent)
        bar = "█" * filled + "-" * (bar_len - filled)

        sys.stdout.write(f"\r[{bar}] {percent:.1%} ({done}/{total})")
        sys.stdout.flush()
    while True:
        # 从输入队列获取任务
        值 = 输入队列.get()

        # 如果任务为None，表示队列结束
        if 值 is None:
            break

        # 任务处理
        序号, 值 = 值
        try:
            # print(f"线程： {线程id} 【{序号} 】 输入：【{值}】")
            结果 = 函数(值)
        except Exception as e:
            print(f"线程： {线程id} 【{序号} 】 输入：【{值}】 error: 【{e}】")
            结果 = None

        # 使用锁确保输出的线程安全
        with 进程锁:
            # print(f"线程：{线程id} 完成")
            输出结果[序号] = 结果
            if 提示进度:
                进度条()


def 多线程(列表, 函数, 线程数, 提示进度=True):
    # 初始变量
    进程锁 = threading.Lock()
    输入队列 = queue.Queue()
    线程列表 = []
    输出结果 = [None]*len(列表)

    # 创建并启动多个线程
    if 提示进度:
        print(f"启动 {线程数} 个线程处理 {len(列表)} 个任务")
    for i in range(线程数):
        thread = threading.Thread(target=二次函数, args=(函数, i, 进程锁, 输入队列, 输出结果, 提示进度))
        thread.start()
        线程列表.append(thread)

    for f1, f2 in enumerate(列表):  # 添加任务到输入队列
        输入队列.put([f1, f2])

    # 添加任务结束标记到输入队列，每个线程一个
    for _ in range(len(线程列表)):
        输入队列.put(None)

    # 等待所有线程结束
    for thread in 线程列表:
        thread.join()
        # print('线程结束-1')

    if 提示进度:
        print('\n多线程处理完成')
    return 输出结果


# if __name__ == "__main__":
#     def test(e):
#         for i in range(3):
#             e += i
#             time.sleep(1)  # 模拟延迟0.1

#         return e

#     test1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#     test2 = 多线程(列表=test1, 函数=test, 线程数=5, 提示进度=True)
#     print(test2)
