Python多线程加速-休眠部分线程

总所周知Python由于GIL的问题,使用多线程时同一时刻只有一个线程在工作。故Python会在所有线程之间不断的切换,每切换到一个线程会执行一段字节码指令然后切换到另一个线程。如果开启了很多线程,且只有小部分线程在工作,如果不休眠部分线程,那么每次切换到非工作线程时就会一直空转浪费资源,从而拖慢了整体效率。例如下面示例代码,总共启动了20个线程,随机分发100个计算10000阶乘的任务。

import time
import random
import threading
from queue import Queue


random.seed(1234)
count = 0
lock = threading.Lock()


def task(v: int):
    res = 1
    for i in range(1, v + 1):
        res = res * i


def worker(input_queue: Queue):
    global count
    while True:
        if input_queue.empty():
            continue

        v = input_queue.get()
        task(v)
        with lock:
            count += 1


if __name__ == '__main__':
    num_workers = 20
    num_tasks = 100
    queues = [Queue() for _ in range(num_workers)]
    threads = [threading.Thread(target=worker, args=(queues[i],)) for i in range(num_workers)]
    for thread in threads:
        thread.daemon = True

    for thread in threads:
        thread.start()
    time.sleep(1)

    t0 = time.perf_counter()
    for _ in range(num_tasks):
        idx = random.randint(0, num_workers - 1)
        queues[idx].put(10000)
    t1 = time.perf_counter()
    print(f"put time: {t1 - t0:.5f}")

    while count != num_tasks:
        continue

    t2 = time.perf_counter()
    print(f"total time: {t2 - t0:.5f}")

终端输出如下:

put time: 24.91427
total time: 26.17514

如果将worker中的continue换成time.sleep(0.02),再次执行终端输出如下:

put time: 0.00038
total time: 1.03202

可以看到,通过time.sleep方法让暂时没工作的线程休眠一会,将更多的工作机会提供给真正需要工作的线程,从而提升了整体效率。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳花的小绿豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值