美文网首页
用Python程序模拟300位观众,为5位嘉宾随机投票,最后按照

用Python程序模拟300位观众,为5位嘉宾随机投票,最后按照

作者: 宇宙之一粟 | 来源:发表于2020-09-22 23:45 被阅读0次

用Python程序模拟300位观众,为5位嘉宾随机投票,最后按照降序排列结果

# redis_test2.py
import random
from redis_db import pool
import redis


con = redis.Redis(
        connection_pool=pool
)

try:
    # con.delete("ballot")
    con.zadd("ballot", {"A":0, "B":0, "C":0, "D":0, "E":0})
    names = ["A", "B", "C", "D", "E"]
    
    for i in range(0, 300):
    
        num = random.randint(0,4)
        name = names[num]
        con.zincrby("ballot", 1, name)
    result = con.zrevrange("ballot", 0, -1, "WITHSCORES")
    
    for one in result:
        print(one[0],decode("utf-8"), int(one[1]))

except Exception as e:
  print(e)
finally:
    del con

为什么要引入线程池

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

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

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

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("秒杀活动已经结束")

相关文章

网友评论

      本文标题:用Python程序模拟300位观众,为5位嘉宾随机投票,最后按照

      本文链接:https://www.haomeiwen.com/subject/bjxnyktx.html