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

Posted shawnhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程对象的其他方法守护进程使用多进程实现 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
# 都是实现进程之间的通信的桥梁
# 队列的用法+模型

 

以上是关于进程对象的其他方法守护进程使用多进程实现 socket tcp协议 server端的并发(抢票程序)队列进程之间的通信(IPC)的主要内容,如果未能解决你的问题,请参考以下文章

并发编程 --进程

无法连接到 unix:/var/run/docker.sock 上的 Docker 守护程序。 docker 守护进程是不是正在运行?

一篇文章搞定Python多进程(全)

并发编程目录

python 39

Linux守护进程详解