zoukankan      html  css  js  c++  java
  • 并发编程

     复习网络编程:

    #网络编程

    #套接字--socket   #底层,帮助你完成了两台机器之间的通信,封装了IP协议、端口、tcp协议,底层的arp协议等等。只是提供给你一个接口而已。

    arp协议:通过IP找mac地址的过程叫arp协议

    #TCP协议特点:可靠的、面向连接的、流传输、消息无边界

        #三次握手(建立连接时)和四次挥手(断开连接时)

    #UDP协议特点:不可靠、无连接的。数据包传输。UDP协议不会发生粘包现象,容易丢数据。

    #粘包现象:在发送数据的时候先发送数据的长度,再接收端先接收数据的长度,再根据数长度接收数据。struct

    一、Socketserver

    这两个都是python中的内置模块

    socket

    socketserver--在socket底层模块上封装

    #网络编程举例:

    server端:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # tcp协议的socket

    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',9999))
    sk.listen() # 允许最大的等待链接数

    conn,addr = sk.accept() # 获取到一个连接
    print(conn)
    while True:
    conn.send(b'hello')
    msg = conn.recv(1024)
    print(msg)
    conn.close()
    sk.close()


    client端:
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',9999))
    while True:
    print(sk.recv(1024))
    sk.send(b'bye')
    sk.close()

    执行顺序,先启动server端再启动client端,可以看到client端一直输出‘bye’死循环,client端一直输出‘hello’死循环

    #socketserver举例:

    server端:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import time
    import socketserver
    class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
    conn = self.request
    print(conn)
    time.sleep(3)
    conn.send(b'hello')
    time.sleep(5)
    conn.send(b'hello2')
    # socketserver
    # socket

    myserver = socketserver.ThreadingTCPServer(('127.0.0.1',9000),Myserver)
    myserver.serve_forever()

    # socketserver所启动的服务端是不能有input操作的
    # server端一般都是根据client端的要求去执行固定的代码
    # 20函数


    client端:
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',9000))
    print(sk.recv(1024))
    print(sk.recv(1024))
    sk.close()
    执行顺序:先执行server端再执行client端代码:
    server端执行结果是:
    <socket.socket fd=312, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 57276)>

    client端输出的是:

    b'hello'
    b'hello2'

    二、并发编程
    1、# 并发编程?
    # 一个程序 可以在同一时刻做多件事情
    # 解决程序中的IO操作影响程序效率的问题
    # 并发编程为什么重要?


    # 操作系统
    # 并发这件事

    # 计算机 —— 穿孔纸带


    # 输入输出 —— 大部分时间都不会占用CPU,且会降低你程序的效率
    # input/print
    # 文件 读数据、取数据
    # 网络操作 : 往网线上 发送请求 写
    # 读 从网络上获取数据

    # 现代操作系统:
    # 基于多道批处理系统和分时系统
    # 多个程序、作业在遇到IO操作的时候,操作系统会帮助你进行切换
    # 让CPU的利用率得到最大的提高
    2、进程
    # 进程
    # 什么是进程 :运行中的程序
    # 什么是程序
    # 操作系统 只负责管理调度进程
    # 进程是操作系统中资源分配的最小单位
    # 每一个运行中的程序都需要有自己的内存、资源
    # 都分配给进程 记录执行的状态 管理自己的内存资源

    # 在Python中,每一个运行中的程序 都是一个进程
    # 一个进程 就能做一件事儿
    # 如果有多个进程 —— 就可以做多件事儿
    # 如何用python来开启一个进程

    举例:
    import
    os import time print(os.getpid()) #进程号 time.sleep(1000)

    执行结果:6340

    # Process 进程
    # multi 多元的
    举例:
    import os
    import time
    from multiprocessing import Process
    def func(num):
        print(num,os.getpid())
        time.sleep(0.5)
        print(num, os.getpid())
        time.sleep(0.5)
        print(num, os.getpid())
        time.sleep(0.5)
        print(num,os.getpid())
    
    if __name__ == '__main__':   # windows
        print(os.getpid())
        p = Process(target=func,args=(10,))   # 创造了一个进程
        p.start() # 开启进程
        print(os.getpid())
        time.sleep(1)
        print(os.getpid(),1)
        time.sleep(1)
        print(os.getpid(), 2)

    执行结果:

    6228
    6228
    10 3212
    10 3212
    6228 1
    10 3212
    10 3212
    6228 2

    # 同步 :
    # 异步 :
    # 异步可以有效地提高程序的效率

    # 几个概念:
    # 子进程 :
    # 主进程 : 运行的这个程序
    # 父进程 :

    # 关于print的顺序

    # 进程与进程之间都是异步的
    # 开启一个进程是有时间开销的

    # if __name__ == '__main__':为什么?

    3、进程进阶
    # 什么是进程 : 运行中的程序,计算机中最小的资源分配单位
    # 程序开始执行就会产生一个主进程
    # python中可以主进程中用代码启动一个进程 —— 子进程
    # 同时主进程也被称为父进程
    # 父子进程之间的代码执行是异步的,各自执行自己的
    # 父子进程之间的数据不可以共享
    # 主进程会等待子进程结束之后再结束

    import time
    from multiprocessing import Process
    n = 100
    def func():
        global n
        n = 0
        print('_______')
        time.sleep(10)
    
    # func()
    if __name__ == '__main__':
        Process(target=func).start()
        time.sleep(1)
        print(n)

    执行结果:

    _______
    100

    import time
    from multiprocessing import Process
    def func(n):
        time.sleep(1)
        print('_'*n)
    if __name__ == '__main__':
        for i in range(10):
            Process(target=func, args=(i,)).start()
    #     # 发邮件的操作
        print('十条信息已经都发送完了')
        Process(target=func,args=(1,)).start()
        Process(target=func,args=(2,)).start()
        Process(target=func,args=(3,)).start()
        Process(target=func,args=(4,)).start()
    
    执行结果:
    十条信息已经都发送完了
    
    _
    __
    ___
    ____
    _____
    ______
    _______
    ________
    _________
    _
    __
    ___
    ____
    开启多个子进程
    import time
    from multiprocessing import Process
    def func(n):
        time.sleep(1)
        print('_'*n)
    if __name__ == '__main__':
        # for i in range(10):
        p = Process(target=func, args=(1,))
        p.start()
        print('子进程开始了')
        p.join()    # 阻塞 直到子进程执行完毕之后再继续
        # 发邮件的操作
        print('十条信息已经都发送完了')
    
    执行结果:
    子进程开始了
    _
    十条信息已经都发送完了
    import time
    from multiprocessing import Process
    def func(n):
        time.sleep(1)
        print('_'*n)
    if __name__ == '__main__':
        l = []
        for i in range(10):
            p = Process(target=func, args=(i,))
            p.start()
            l.append(p)
        for p in l:p.join()
        # 发邮件的操作
        print('十条信息已经都发送完了')
    
    执行结果:
    
    _
    __
    ___
    ____
    _____
    ______
    _______
    ________
    _________
    十条信息已经都发送完了
    开启多个子进程2

    # 守护进程
    # 守护进程也是一个子进程
    # 当主进程的代码执行完毕之后自动结束的子进程叫做守护进程
    import time
    from multiprocessing import Process
    import time
    def deamon_func():
        while True:
            print('我还活着')
            time.sleep(0.5)
    
    def wahaha():
        for i in range(10):
            time.sleep(1)
            print(i * '#')
    
    if __name__ == '__main__' :
        p2 = Process(target=wahaha)
        p2.start()
        p = Process(target=deamon_func)
        p.daemon = True
        p.start()
        for i in range(3):
            print(i*'*')
            time.sleep(1)
        p2.join()
    
    执行结果:
    
    我还活着
    我还活着
    *
    
    我还活着
    我还活着
    **
    #
    我还活着
    我还活着
    ##
    我还活着
    我还活着
    ###
    我还活着
    我还活着
    ####
    我还活着
    我还活着
    #####
    我还活着
    我还活着
    ######
    我还活着
    我还活着
    #######
    我还活着
    我还活着
    ########
    我还活着
    我还活着
    #########

    总结:

    # 开启一个子进程 start
    # 子进程和主进程是异步
    # 如果在主进程中要等待子进程结束之后再执行某段代码:join
    # 如果有多个子进程 不能在start一个进程之后就立刻join,把所有的进程放到列表中,等待所有进程都start之后再逐一join
    # 守护进程 —— 当主进程的"代码"执行完毕之后自动结束的子进程叫做守护进程

    4、锁
    举例1:
    import os
    import time
    import random
    from multiprocessing import Process,Lock
    
    def work(n,lock):
        lock.acquire()
        print('%s: %s is running' %(n,os.getpid()))
        time.sleep(random.random())
        print('%s:%s is done' %(n,os.getpid()))
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(3):
            p=Process(target=work,args=(i,lock))
            p.start()
            p.join()
    
    执行结果:
    0: 5940 is running
    0:5940 is done
    1: 2808 is running
    1:2808 is done
    2: 4628 is running
    2:4628 is done
    # 牺牲效率但是保证了数据的安全 
    举例2:
    前提有个db文件:内容{"count": 1}
    from multiprocessing import Process,Lock
    import time,json,random
    def search():
        dic=json.load(open(r'D:老男孩教育老师的笔记和视频day09day9视频与笔记day92-并发编程进程db'))
        print('33[43m剩余票数%s33[0m' %dic['count'])
    
    def get(num):
        dic=json.load(open(r'D:老男孩教育老师的笔记和视频day09day9视频与笔记day92-并发编程进程db'))
        time.sleep(random.random()) #模拟读数据的网络延迟
        if dic['count'] >0:
            dic['count']-=1
            time.sleep(random.random()) #模拟写数据的网络延迟
            json.dump(dic,open(r'D:老男孩教育老师的笔记和视频day09day9视频与笔记day92-并发编程进程db','w'))
            print('33[43m%s购票成功33[0m'%num)
    
    def task(num,lock):
        search()
        lock.acquire()
        get(num)
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(10): #模拟并发100个客户端抢票
            p=Process(target=task,args = (i,lock))
            p.start()
    
    执行结果:
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    剩余票数1
    0购票成功

    5、信号量

    举例1:
    from  multiprocessing import Semaphore
    sem = Semaphore(5)
    sem.acquire()
    print(1)
    sem.acquire()
    print(2)
    sem.acquire()
    print(3)
    sem.acquire()
    print(4)
    sem.acquire()
    print(5)
    sem.acquire()   # 要拿钥匙
    print(6)
    
    执行结果:
    1
    2
    3
    4
    5
    举例2:
    from multiprocessing import Process,Semaphore
    import time,random
    
    def go_ktv(sem,user):
        sem.acquire()
        print('%s 占到一间ktv小屋' %user)
        time.sleep(random.randint(3,5)) #模拟每个人在ktv中待的时间不同
        sem.release()
        print('%s 走出ktv小屋' % user)
    
    if __name__ == '__main__':
        sem=Semaphore(4)
        p_l=[]
        for i in range(13):
            p=Process(target=go_ktv,args=(sem,'user%s' %i,))
            p.start()
            p_l.append(p)
    
        for i in p_l:
            i.join()
        print('============》')
    
    执行结果:
    user0 占到一间ktv小屋
    user2 占到一间ktv小屋
    user1 占到一间ktv小屋
    user3 占到一间ktv小屋
    user4 占到一间ktv小屋
    user0 走出ktv小屋
    user1 走出ktv小屋
    user6 占到一间ktv小屋
    user2 走出ktv小屋
    user5 占到一间ktv小屋
    user3 走出ktv小屋
    user7 占到一间ktv小屋
    user4 走出ktv小屋
    user8 占到一间ktv小屋
    user6 走出ktv小屋
    user10 占到一间ktv小屋
    user5 走出ktv小屋
    user9 占到一间ktv小屋
    user11 占到一间ktv小屋
    user10 走出ktv小屋
    user7 走出ktv小屋
    user12 占到一间ktv小屋
    user8 走出ktv小屋
    user9 走出ktv小屋
    user12 走出ktv小屋
    user11 走出ktv小屋
    ============》

    总结:

    # 信号量的本质就是 锁+计数器

    6、事件
    # 事件内部内置了一个标志
    # wait 方法 如果这个标志是True,那么wait == pass
    # wait 方法 如果这个标志是False,那么wait就会陷入阻塞,一直阻塞到标志从False变成True

    # 一个事件在创建之初 内部的标志默认是False
    # Flase -> True set()
    # True -> False clear()
    from multiprocessing import Process, Event
    import time, random
    
    def car(e, n):
        while True:
            if not e.is_set():  # 进程刚开启,is_set()的值是Flase,模拟信号灯为红色
                print('33[31m红灯亮33[0m,car%s等着' % n)
                e.wait()    # 阻塞,等待is_set()的值变成True,模拟信号灯为绿色
                print('33[32m车%s 看见绿灯亮了33[0m' % n)
                time.sleep(random.randint(3, 6))
                if not e.is_set():   #如果is_set()的值是Flase,也就是红灯,仍然回到while语句开始
                    continue
                print('车开远了,car', n)
                break
    
    def traffic_lights(e, inverval):
        while True:
            time.sleep(inverval)   # 先睡3秒
            if e.is_set():         # 标志是True
                print('######', e.is_set())
                e.clear()  # ---->将is_set()的值设置为False
            else:                 # 标志是False
                e.set()    # ---->将is_set()的值设置为True
                print('***********',e.is_set())
    
    
    if __name__ == '__main__':
        e = Event()   #e就是事件
        t = Process(target=traffic_lights, args=(e, 3))  # 创建一个进程控制红绿灯
        for i in range(10):
            p=Process(target=car,args=(e,i,))  # 创建是个进程控制10辆车
            p.start()
        t.start()
    
        print('============》')
    
    
    执行结果:
    
    红灯亮,car0等着
    红灯亮,car1等着
    红灯亮,car2等着
    红灯亮,car3等着
    红灯亮,car4等着
    红灯亮,car5等着
    红灯亮,car6等着
    红灯亮,car7等着
    ============》
    红灯亮,car8等着
    红灯亮,car9等着
    车0 看见绿灯亮了
    车2 看见绿灯亮了
    车4 看见绿灯亮了
    车8 看见绿灯亮了
    车6 看见绿灯亮了
    车1 看见绿灯亮了
    车5 看见绿灯亮了
    车3 看见绿灯亮了
    车9 看见绿灯亮了
    *********** True
    车7 看见绿灯亮了
    车开远了,car 4
    车开远了,car 6
    ###### True
    红灯亮,car8等着
    红灯亮,car1等着
    红灯亮,car5等着
    红灯亮,car7等着
    红灯亮,car9等着
    红灯亮,car3等着
    红灯亮,car2等着
    红灯亮,car0等着
    车2 看见绿灯亮了
    车8 看见绿灯亮了
    车0 看见绿灯亮了
    车1 看见绿灯亮了
    车5 看见绿灯亮了
    车9 看见绿灯亮了
    车7 看见绿灯亮了
    *********** True
    车3 看见绿灯亮了
    车开远了,car 2
    ###### True
    红灯亮,car0等着
    红灯亮,car7等着
    红灯亮,car9等着
    红灯亮,car8等着
    红灯亮,car3等着
    红灯亮,car5等着
    红灯亮,car1等着
    车0 看见绿灯亮了
    车8 看见绿灯亮了
    车7 看见绿灯亮了
    车1 看见绿灯亮了
    车5 看见绿灯亮了
    *********** True
    车9 看见绿灯亮了
    车3 看见绿灯亮了
    车开远了,car 1
    ###### True
    红灯亮,car5等着
    红灯亮,car8等着
    红灯亮,car7等着
    红灯亮,car9等着
    红灯亮,car3等着
    车3 看见绿灯亮了
    车8 看见绿灯亮了
    车7 看见绿灯亮了
    车5 看见绿灯亮了
    车9 看见绿灯亮了
    *********** True
    ###### True
    红灯亮,car0等着
    红灯亮,car8等着
    红灯亮,car9等着
    红灯亮,car3等着
    红灯亮,car7等着
    车8 看见绿灯亮了
    车9 看见绿灯亮了
    车0 看见绿灯亮了
    车3 看见绿灯亮了
    车7 看见绿灯亮了
    *********** True
    ###### True
    红灯亮,car5等着
    红灯亮,car0等着
    红灯亮,car3等着
    车开远了,car 7
    车开远了,car 9
    车5 看见绿灯亮了
    车0 看见绿灯亮了
    *********** True
    车3 看见绿灯亮了
    ###### True
    红灯亮,car8等着
    红灯亮,car5等着
    红灯亮,car3等着
    红灯亮,car0等着
    车0 看见绿灯亮了
    车8 看见绿灯亮了
    车5 看见绿灯亮了
    *********** True
    车3 看见绿灯亮了
    车开远了,car 8
    ###### True
    红灯亮,car5等着
    红灯亮,car3等着
    车5 看见绿灯亮了
    车开远了,car 0
    车3 看见绿灯亮了
    *********** True
    ###### True
    车开远了,car 3
    红灯亮,car5等着
    *********** True
    车5 看见绿灯亮了
    ###### True
    红灯亮,car5等着
    *********** True
    车5 看见绿灯亮了
    ###### True
    红灯亮,car5等着
    车5 看见绿灯亮了
    *********** True
    ###### True
    红灯亮,car5等着
    *********** True
    车5 看见绿灯亮了
    ###### True
    红灯亮,car5等着
    车5 看见绿灯亮了
    *********** True
    ###### True
    车开远了,car 5
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    ###### True
    *********** True
    # 红绿灯模型
    # 10个进程 模拟车 :车的行走要依靠当时的交通灯
    # 交通灯是绿灯 车就走
    # 交通灯是红灯 车就停 停到灯变绿
    # wait 来等灯
    # set clear 来控制灯

    7、队列
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from multiprocessing import Queue,Process
    
    def func(q,num):
        try:
            t = q.get_nowait()
            print("%s抢到票了"%num)
        except:pass
    
    if __name__ == '__main__':
        q = Queue()
        q.put(1)
        for i in range(10):
            Process(target=func,args=(q,i)).start()
    
    执行结果:
    0抢到票了
    # 管道 + 锁  == 队列
    # 管道也是一个可以实现进程之间通信的模型
    # 但是管道没有锁,数据不安全

    # 消息中间件
    # memcache
    # rabitmq
    # kafka —— 大数据相关
    # redis

    8、数据共享
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from multiprocessing import Manager,Process,Lock
    def work(d,lock):
        with lock: #不加锁而操作共享的数据,肯定会出现数据错乱
            d['count']-=1
    
    if __name__ == '__main__':
        lock=Lock()
        m = Manager()
        dic = m.dict({'count':100})
        #dic = {'count':100}
        p_l=[]
        for i in range(50):
            p=Process(target=work,args=(dic,lock))
            p_l.append(p)
            p.start()
        for p in p_l:
            p.join()
        print(dic)
    
    执行结果:
    {'count': 50}
     










  • 相关阅读:
    jackson 枚举 enum json 解析类型 返回数字 或者自定义文字 How To Serialize Enums as JSON Objects with Jackson
    Antd Pro V5 中ProTable 自定义查询参数和返回值
    ES6/Antd 代码阅读记录
    es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?
    Antd Hooks
    使用.Net Core开发WPF App系列教程(其它 、保存控件内容为图片)
    使用.Net Core开发WPF App系列教程( 三、与.Net Framework的区别)
    使用.Net Core开发WPF App系列教程( 四、WPF中的XAML)
    使用.Net Core开发WPF App系列教程( 二、在Visual Studio 2019中创建.Net Core WPF工程)
    使用.Net Core开发WPF App系列教程( 一、.Net Core和WPF介绍)
  • 原文地址:https://www.cnblogs.com/lucky-penguin/p/9171271.html
Copyright © 2011-2022 走看看