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()
posted @ 2021-04-25 21:23  黑影Poco  阅读(165)  评论(0)    收藏  举报