请问老师线程池线程数量的问题

来源:2-11 课堂练习:模拟商品秒杀活动案例(二)

马铃薯胖鸭

2019-08-29 17:18:15

import random
from concurrent.futures.thread import ThreadPoolExecutor
import redis

pool = redis.ConnectionPool(
    host="localhost",
    port=6379,
    db=2,
    max_connections=20
)
con = redis.Redis(
    connection_pool=pool
)

people = set()
for i in range(0,1000):
    temp = random.randint(1000, 999999)
    people.add(temp)
print(people)
print(len(people))





try:
    con.delete('k_num','k_total','k_buy','k_flag')
    k_num = con.set('k_num',0)
    k_total = con.set('k_total',50)
    k_flag = con.set('k_flag',1)
    con.expire('k_flag',600)
except Exception as e:
    print(e)
finally:
    del con


def ms():
    connection = redis.Redis(
        connection_pool=pool
    )
    pipline = connection.pipeline()
    try:
        if connection.exists('k_flag'):
            pipline.watch('k_num', 'k_buy')
            num = int(pipline.get('k_num').decode('utf-8'))
            total = int(pipline.get('k_total').decode("utf-8"))

            if num < total:
                pipline.multi()
                p_buy = people.pop()
                pipline.rpush('k_buy',p_buy)
                pipline.incrby('k_num')
                pipline.execute()
    except:
        pass
    finally:
        pipline.reset()
        del connection

executor = ThreadPoolExecutor(max_workers=50)
for i in range(len(people)):
    executor.submit(ms)

我测试了好几次,为什么偏偏在线程数量为50的时候会出现少于规定数量的数据,线程数量为20,100的时候就没问题,这里面出了什么问题吗

写回答

1回答

慕之熠_灿烈

2019-08-29

同学,你好。

针对本问题,首先需要明确两个概念:(1)当把线程任务提交给Python的线程池之后,关于线程的“管理权”也就交给了线程池来自动管理;(2)Redis是利用单线程技术的非关系型数据库。

线程池的任务是并发执行的,当一个线程执行完毕后或因阻塞性任务而让出CPU的使用权后,会马上执行另一个的线程,这种执行原则是无序的,类似与Python的多线程,当一个线程执行完毕后会返回对应线程的执行结果(该结果是Future类型,了解即可)。正因为并发执行线程池中的任务,所以在Redis中事务管理需要对目标数据进行“监视”,即:“Watched variable changed”,从而有效的避免其他线程对目标数据进行“非法”修改。

如果我的回答解决了您的疑惑,请采纳!祝~学习愉快~


0

0 学习 · 2669 问题

查看课程