29、高并发tcp服务端和进程锁实现
一、高并发的tcp服务端
实现 服务端可以一次 服务多个客户端
import socket
from multiprocessing import Process
def talk(sock, addr):
print('客户端连接成功', addr)
while True:
try:
data = sock.recv(1024) # 接 受客户端传来的信息
if len(data) == 0: # 表示客户端正常断开了,结束通信循环
break
print(data.decode('utf-8')) # 解码,打印用户消息
sock.send(data.upper()) # 服务端给客户端发送消息
except Exception as e: # 表示客户端非正常断开,需要异常捕获
print(e)
break
sock.close() # 关闭连接对象
if __name__ == '__main__':
server = socket.socket()
server.bind(('127.0.0.1', 8008)) # 绑定地址跟端口
server.listen(5) # 监听
print('开始等待客户端连接')
while True:
sock, addr = server.accept() # 等待用户连接
p = Process(target=talk, args=[sock, addr])
p.start()
server.close() # 关闭服务
二、进程锁
通过运行结果我们可以看出,多个子进程一起执行。我们如何使其运行一个进程,等到结束时再执行下一个进程呢,这里我们就需要用到进程锁了
from multiprocessing import Process
import time
import random
def pao(name):
print('%s 起床了' % name)
time.sleep(random.randrange(1, 5))
print('%s 休息了' % name)
if __name__ == '__main__':
list1 = ['1号选手小猪佩奇', '2号选手猪猪侠', '3号选手光头强', '4号选手懒羊羊']
for k in list1:
p1 = Process(target=pao, args=[k])
p1.start()
'''
2号选手猪猪侠 起床了
1号选手小猪佩奇 起床了
3号选手光头强 起床了
4号选手懒羊羊 起床了
2号选手猪猪侠 休息了
1号选手小猪佩奇 休息了
4号选手懒羊羊 休息了
3号选手光头强 休息了
'''
给程序上进程锁,使其串行运行程序,这样就实现了一个进程从执行到结束,才会轮到下一个进程执行。
from multiprocessing import Process
from multiprocessing import Lock # 导入进程锁的模块
import time
import random
def pao(name, lock):
lock.acquire() # 上锁
print('%s 起床了' % name)
time.sleep(random.randrange(1, 5))
print('%s 休息了' % name)
lock.release() # 释放锁
if __name__ == '__main__':
list1 = ['1号选手小猪佩奇', '2号选手猪猪侠', '3号选手光头强', '4号选手懒羊羊']
lock = Lock() # 生产一把锁,在主进程中生产
for k in list1:
p1 = Process(target=pao, args=[k, lock])
p1.start()
'''
1号选手小猪佩奇 起床了
1号选手小猪佩奇 休息了
3号选手光头强 起床了
3号选手光头强 休息了
2号选手猪猪侠 起床了
2号选手猪猪侠 休息了
4号选手懒羊羊 起床了
4号选手懒羊羊 休息了
'''
三、模拟抢票功能
# 用文件模拟只有一张火车票
{"count": 1}
未加进程锁之前
明明只有一张票,却被所有人买成功了
from multiprocessing import Process
import json, time
def check(i): # 查看票数
with open('a.txt', 'rt', encoding='utf-8') as f:
res = json.load(f)
print('%s:在查询票数,票还剩%s张' % (i, res['count']))
if res['count'] > 0:
return True
def buy(i): # 抢票,
with open('a.txt', 'rt', encoding='utf-8') as f:
res = json.load(f) # 抢票前还需要再查票
time.sleep(1) # 模拟查票延迟
if res['count'] > 0:
print('%s现在要买票了' % i)
res['count'] -= 1
time.sleep(2) # 模拟买票延迟
with open('a.txt', 'wt', encoding='utf-8') as f1:
json.dump(res, f1)
print('%s购票成功' % i)
else:
print('%s购票失败,票数不足' % i)
def task(i):
res = check(i)
if res:
buy(i)
if __name__ == '__main__':
for i in range(10):
p = Process(target=task, args=[i])
p.start()
加上进程锁
加上进程锁,我们就实现十个人买票,,只有一个人能买成功!
from multiprocessing import Process, Lock
import json, time
def check(i): # 查看票数
with open('a.txt', 'rt', encoding='utf-8') as f:
res = json.load(f)
print('%s:在查询票数,票还剩%s张' % (i, res['count']))
if res['count'] > 0:
return True
def buy(i): # 抢票,
with open('a.txt', 'rt', encoding='utf-8') as f:
res = json.load(f) # 抢票前还需要再查票
time.sleep(1) # 模拟查票延迟
if res['count'] > 0:
print('%s现在要买票了' % i)
res['count'] -= 1
time.sleep(2) # 模拟买票延迟
with open('a.txt', 'wt', encoding='utf-8') as f1:
json.dump(res, f1)
print('%s购票成功' % i)
else:
print('%s购票失败,票数不足' % i)
def task(i, lock):
res = check(i)
if res:
lock.acquire() # 上锁
buy(i)
lock.release() # 释放锁
if __name__ == '__main__':
lock = Lock() # 在主进程创建锁
for i in range(10):
p = Process(target=task, args=[i, lock])
p.start()

浙公网安备 33010602011771号