• 进程对象的其他方法、守护进程、使用多进程实现 socket tcp协议 server端的并发(抢票程序)、队列、进程之间的通信(IPC)


    # 进程对象的其他方法
    
    from multiprocessing import Process
    import time
    
    class MyProcess(Process):
    
        def __init__(self, a, b):  # 为了给子进程传递参数
            super().__init__()
            self.a = a
            self.b = b
    
        def run(self):
            print("子进程开始执行")
            time.sleep(2)
            print("子进程结束", self.a, self.b)
    
    if __name__ == "__main__":
        p = MyProcess(1, 2)
        p.start()
        print(p.is_alive())
        time.sleep(1)
        print(p.name)  # MyProcess-1
        p.terminate()  # 非阻塞
        print(p.is_alive())
        time.sleep(0.5)
        print(p.is_alive())
    
    # True
    # 子进程开始执行
    # MyProcess-1
    # True
    # False
    # 守护进程
    
    import time
    from multiprocessing import Process
    
    def eye():
        while True:
            print("我是子进程, 告诉server端我很好")
            time.sleep(2)
    
    def main():
        print("我想做的事情")
    
    if __name__ == "__main__":
        p = Process(target=eye)
        p.start()
        main()
    
    # 我想做的事情
    # 告诉server端我很好
    # 告诉server端我很好
    # .
    # .
    
    # 因为设置了时间延迟,因此先执行主进程的main()
    # 另外,每隔2s执行子进程
    import time
    
    from multiprocessing import Process
    
    def eye():
        while True:
            print("我是守护进程, 每隔2s告诉server端我很好")
            time.sleep(2)
    
    def main():
        print("我是主进程, 5s后我将结束运行")
        time.sleep(5)
        print("主进程结束后,守护进程也不再执行")
    
    if __name__ == "__main__":
        p = Process(target=eye)
        p.daemon = True  # p进程设置成 守护进程
        p.start()
        main()
    
    # 我是主进程, 5s后我将结束运行
    # 我是守护进程, 每隔2s告诉server端我很好
    # 我是守护进程, 每隔2s告诉server端我很好
    # 我是守护进程, 每隔2s告诉server端我很好
    # 主进程结束后,守护进程也不再执行
    
    # 守护进程:只要主进程的代码结束,子进程也会随之结束
    import time
    from multiprocessing import Process
    
    def eye():
        while True:
            print("我是守护进程, 我只守护主进程,每隔2s告诉server端我很好")
            time.sleep(2)
    
    def process2():
        print("我是子进程, 8s后我就结束运行,守护进程不会守护我")
        time.sleep(8)
        print("我是子进程, 我现在结束运行,主进程也跟着结束")
    
    def main():
        print("我是主进程,5s后我将结束运行")
        time.sleep(5)
        print("5s过去了,但是子进程还没结束,要等它结束我才能结束")
    
    if __name__ == "__main__":
        p = Process(target=eye)
        p2 = Process(target=process2)
        p.daemon = True  # p进程设置成 守护进程
        p.start()
        p2.start()
        main()
    
    # 我是主进程,5s后我将结束运行
    # 我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
    # 我是子进程, 8s后我就结束运行,守护进程不会守护我
    # 我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
    # 我是守护进程, 我只守护主进程,每隔2s告诉server端我很好
    # 5s过去了,但是子进程还没结束,要等它结束我才能结束
    # 我是子进程, 我现在结束运行,主进程也跟着结束
    
    # 守护进程只守护主进程,不会守护子进程
    import time
    from multiprocessing import Process
    
    def eye():
        while True:
            print("我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好")
            time.sleep(2)
    
    def process2():
        print("我是子进程,12s后我就结束运行")
        time.sleep(12)
        print("我是子进程,我现在结束运行")
    
    def main():
        print("我是主进程,5s后我就结束运行")
        time.sleep(5)
        print("我是主进程,我现在结束运行")
    
    if __name__ == "__main__":
        p = Process(target=eye)
        p2 = Process(target=process2)
        p.daemon = True  # p进程设置成 守护进程
        p.start()
        p2.start()
        main()
        p2.join()
    # p2 结束之后这句代码才会结束
    # 如果想让守护进程守护子进程,则像上面这样把子进程加个join就行
    
    # 我是主进程,5s后我就结束运行
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是子进程,12s后我就结束运行
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是主进程,我现在结束运行
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是守护进程, 我现在守护主进程和子进程,每隔2s告诉它们我很好
    # 我是子进程,我现在结束运行
    
    # 总结
    # 1.守护进程 会随着主进程代码的结束而结束
    # 2.守护进程不会守护除了主进程代码之外的其他子进程
    # 使用多进程实现 socket tcp协议 server端的并发
    
    # server.py
    
    import socket
    from multiprocessing import Process
    
    def func(conn):
        while 1:
            conn.send("我会一直向客户端发送这个信息".encode())
    
    if __name__ == "__main__":
        sk = socket.socket()
        sk.bind(("127.0.0.1", 8080))
        sk.listen()
        while 1:
            conn, addr = sk.accept()
            p = Process(target=func, args=(conn,))
            p.start()
    # client.py
    
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 8080))
    
    while True:
        msg = sk.recv(1024)
        print(msg.decode())
    
    # 我会一直向客户端发送这个信息
    # 我会一直向客户端发送这个信息
    # 我会一直向客户端发送这个信息
    # ...
    # 还可以创建多个client端同时运行
    
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 8080))
    
    while True:
        msg = sk.recv(1024)
        print(msg)
    # 抢票的例子
    # 先查看余票,再抢票,注意是并发
    
    # 先创建一个 ticket 的文件, 内容如下:
    # {"count": 3}
    # 3表示还有3张票
    
    import json
    import time
    from multiprocessing import Process
    from multiprocessing import Lock
    
    def search(name):
        with open("ticket") as f:
            ticket_count = json.load(f)
        if ticket_count["count"] >= 1:
            print("%s号注意了: 有余票%s张" % (name, ticket_count["count"]))
        else:
            print("%s号注意: 没票了" % name)
    
    def buy(name):
        with open("ticket") as f:
            ticket_count = json.load(f)
        time.sleep(0.2)
        if ticket_count["count"] >= 1:
            print("有余票%s张" % ticket_count["count"])
            ticket_count["count"] -= 1
            print("%s号买到票了" % name)
        else:
            print("%s号没买到票" % name)
        with open("ticket", "w") as f:
            json.dump(ticket_count, f)
    
    def opt(lock, name):
        search(name)
        lock.acquire()
        buy(name)
        lock.release()
    
    if __name__ == "__main__":
        lock = Lock()  # 保证数据安全,不超票
        for i in range(10):
            p = Process(target=opt, args=(lock, "alex"+str(i),))
            p.start()
    
    # alex1号注意了: 有余票3张
    # alex2号注意了: 有余票3张
    # alex0号注意了: 有余票3张
    # alex3号注意了: 有余票3张
    # alex4号注意了: 有余票3张
    # alex7号注意了: 有余票3张
    # alex5号注意了: 有余票3张
    # alex6号注意了: 有余票3张
    # alex9号注意了: 有余票3张
    # alex8号注意了: 有余票3张
    # 有余票3张
    # alex1号买到票了
    # 有余票2张
    # alex2号买到票了
    # 有余票1张
    # alex0号买到票了
    # alex3号没买到票
    # alex4号没买到票
    # alex7号没买到票
    # alex5号没买到票
    # alex6号没买到票
    # alex9号没买到票
    # alex8号没买到票
    
    # 多个进程抢占同一个数据资源会造成数据不安全
    # 必须要牺牲效率来保证数据的安全性
    # 队列:维护了一个秩序,先进先出,FIFO(first in first out)
    
    import queue
    
    q = queue.Queue()
    print(q)  # <queue.Queue object at 0x0000029753908710>
    q.put(1)
    q.put(2)
    q.put(3)
    print(q)  # <queue.Queue object at 0x0000029753908710>
    
    print(q.get())  # 1
    print(q.get())  # 2
    print(q.get())  # 3
    # 进程之间的通信 IPC(Iter Process Communication)
    
    from multiprocessing import Queue, Process
    
    def son(q):
        msg1 = q.get()
        print(msg1)
        msg2 = q.get()
        print(msg2)
        msg3 = q.get()
        print(msg3)
    
    if __name__ == "__main__":
        q = Queue()  # 队列是进程之间数据安全的数据类型,基于pickle + socket + Lock
        pro = Process(target=son, args=(q, ))
        pro.start()
        q.put("我是第一个被放进去的,取数据的时候我第一个出来")
        q.put("我是第二个被放进去的")
        q.put("我是最后被放进去的")
    
    # 我是第一个被放进去的,取数据的时候我第一个出来
    # 我是第二个被放进去的
    # 我是最后被放进去的
    
    # 还有一个管道Pipe,没有锁,数据不安全,这里暂不了解其用法
    # 其实队列就是管道+锁的结合
    
    # 第三方工具(消息中间件):memocache, redis, kafka, rabbitmq
    # 都是实现进程之间的通信的桥梁
    # 队列的用法+模型
  • 相关阅读:
    Spring-boot 项目中使用 jackson 遇到的一个问题
    Spring Cloud 简介
    VSCode配置JAVA开发环境
    Smtp错误码
    Git遇到的问题
    对于static静态
    面向对象
    类与对象的概念
    java执行过程
    nacos安装部署
  • 原文地址:https://www.cnblogs.com/shawnhuang/p/10323695.html
Copyright © 2020-2023  润新知