为什么需要线程池?

2020-10-26 10:35:24 浏览数 (1)

为什么要引入线程池

如果在程序中经常要用到线程,频繁的创建和销毁线程会浪费很多硬件资源,

所以需要把线程和任务分离。线程可以反复利用,省去了重复创建的麻烦。

代码语言:javascript复制
from concurrent.futures import ThreadPoolExecutor

def say_hello():
    print("Hello")
    
executor = ThreadPoolExecutor(50)
for i in range(0, 10):
   executor.submit(say_hello)

练习三:

利用Python多线程模拟商品秒杀过程,不可以出现超买和超卖的情况。假设A商品有50件参与秒杀活动,10分钟秒杀自动结束。

kill_total 商品总数

kill_num 成功抢购数

kill_flag 有效标志位

kill_user 成功抢购的用户ID

代码语言:javascript复制
from redis_db import pool
import redis
import random
from concurrent.futures import ThreadPoolExecutor

s = set()
while True:
    if len(s) == 1000:
        break
    num = random.randint(10000, 100000)
    s.add(num)
print(s)

con = redis.Redis(
        connection_pool=pool
)

try:
    con.delete("kill_total", "kill_num", "kill_flag", "kill_user")
    con.set("kill_total", 50)
    con.set("kill_num", 0)
    con.set("kill_flag", 1)
    con.expire("kill_flag", 600)
    
except Exception as e:
    print(e)
finally:
    del con
    
executor = ThreadPoolExecutor(200)
def buy():
    connection = redis.Redis(
            connection_pool=pool
    )
    pipline = connection.pipline()
    try:
        if connection.exists("kill_flag") == 1:
                pipline.watch("kill_num", "kill_user")
            total = pipline.get("kill_total")
            num = int(pipline.get("kill_num").decode("utf-8"))
            if num < total:
                pipline.multi()
                pipline.incr("kill_num")
                user_id = s.pop()
                pipline.rpush("kill_user", user_id)
                
                pipline.execute()
    except Exception as e:
        print(e)
    finally:
        if "pipline" in dir():
            pipline.reset()
        del connection
 
for i in range(0, 1000):
        executor.submit(buy)
print("秒杀活动已经结束")

0 人点赞