本示例模拟火车抢票的场景,使用线程锁,避免线程之间相互占用,理解线程锁。
首先构建一个购买火车票的接口,模拟只剩下最后4张票对外提供,每购买成功一次就减少一张火车票。
a = 4
ticket_list = []
fake = Faker('zh_CN')
for i in range(1, 5):
ticket_data = TicketData()
ticket_data.address_from = fake.city()
ticket_data.address_to = fake.city()
ticket_data.date_from = (
datetime.datetime.now() +
datetime.timedelta(
days=10)).strftime("%Y-%m-%d")
ticket_data.date_to = (
datetime.datetime.now() +
datetime.timedelta(
days=20)).strftime("%Y-%m-%d")
ticket_data.book_id = fake.random_number(digits=20)
ticket_list.append(ticket_data)
def main(request):
global a
global ticket_list
try:
# print(a)
random_num = random.randint(0, a)
# print(random_num)
rsp_ticket = ticket_list[random_num]
except Exception as e:
# print(e)
rsp = '对不起票已经抢完'
return HttpResponse(rsp, charset='utf-8')
rsp = f'恭喜你抢票成功,票信息为出发日期{rsp_ticket.date_from},终止日期{rsp_ticket.date_to},出发地{rsp_ticket.address_from},达到地点{rsp_ticket.address_to},票面号{rsp_ticket.book_id}'
del ticket_list[random_num]
a -= 1
return HttpResponse(rsp, charset='utf-8')
其中ticket的对象定义如下
class TicketData(object):
def __init__(self, address_from='', address_to='', date_from='', date_to='', book_id=''):
self.address_from = address_from
self.address_to = address_to
self.date_from = date_from
self.date_to = date_to
self.book_id = book_id
项目代码:https://gitee.com/penn520/simple_django_demo/
然后模拟20个用户一起购买火车票,对请求加了线程锁,代码如下
def get_ticket(url):
lock = threading.Lock()
try:
lock.acquire()
rsp = requests.get(url)
finally:
lock.release()
print(rsp.text)
if __name__ == '__main__':
for i in range(1, 20):
t = threading.Thread(name='thread-%d' % (i,), target=get_ticket, args=('http://localhost:5555/demo/demoFake',))
t.start()
time.sleep(0.1)
结果信息:
对不起票已经抢完
恭喜你抢票成功,票信息为出发日期2022-10-06,终止日期2022-10-16,出发地齐齐哈尔市,达到地点太原市,票面号8785297787110115443
恭喜你抢票成功,票信息为出发日期2022-10-06,终止日期2022-10-16,出发地博市,达到地点淮安市,票面号23897310924959357684
恭喜你抢票成功,票信息为出发日期2022-10-06,终止日期2022-10-16,出发地佛山县,达到地点丹丹市,票面号87125665695145728660
对不起票已经抢完
对不起票已经抢完
恭喜你抢票成功,票信息为出发日期2022-10-06,终止日期2022-10-16,出发地琴市,达到地点天津市,票面号37967511222061123215
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完
对不起票已经抢完