Python中多进程深入解析(3)

# 通信任务
def talk(conn):
    while True:
        try:
            data = conn.recv(1024)
            print('客户端的数据:',data)
            conn.send(data.upper())
        except ConnectionResetError:
            break
    conn.close()

# 连接任务
def server(ip,port):
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server.bind((ip,port))
    server.listen()

while True:
        conn,addr = server.accept()
        p = Process(target=talk,args=(conn,))
        p.start()

server.close()

if __name__ == '__main__':
    server('127.0.0.1',9991)
   
   
#!/usr/bin/python3

#socket客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',9991))

while True:
    msg = input('>>>').strip()
    if not msg:continue
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print(data.decode('utf-8'))

client.close()

那么代码经过这样的改动的话,服务端开放9991端口后,每运行一个客户端就相当于一个进程去连接服务端,就实现了基于socket网络通信+多进程的方式了

查看进程的PID

在操作系统中,有一个进程ID号,代表着当前这个进程运行着什么功能。

# 在linux中使用ps aux就可以查看,其中'T'代表停止状态,表示目前PID暂时没有被回收
root      1197  0.0  0.6 131932  6664 pts/2    T    17:15  0:00 python3 客户端.py
root      1198  0.0  0.6 141588  6416 pts/0    T    17:15  0:00 python3 服务端.py

让我们来看下子进程的PID,在windosw下举例:

from multiprocessing import Process
import os
import time

def task():
    print('%s is running,parent id is <%s>.'%(os.getpid(),os.getppid()))  # 子进程ID,父进程ID
    time.sleep(3)
    print('%s is done,parent id is <%s>.'%(os.getpid(),os.getppid()))

if __name__ == '__main__':
    p = Process(target=task,)
    p.start()
    print('主进程',os.getpid(),os.getppid())  # 主进程的ID,主进程的父亲ID
   
# 那么运行结果是这样的
主进程 5308 8332
10408 is running,parent id is <5308>.
10408 is done,parent id is <5308>.

我们之前说过了,当一个主进程中开启子进程,那么子进程会去拷贝父进程中的数据作为子进程的原始数据,so,主进程的ID是10408,父进程的ID是5308。

那么8332是个什么鬼,我给你看个东西你就懂了
C:\Users\xiaoyafei>tasklist | findstr pycharm
pycharm64.exe                8332 Console                    3  1,108,664 K

看到了吗?是pycharm的进程号。

僵尸进程和孤儿进程(了解)

所谓僵尸进程:就是在主进程开启了一个子进程后,无论什么时候都可以去查看子进程的状态,即使子进程死掉了,也要为主进程保留子进程状态信息,僵尸进程是有害的,因为一个进程死掉后,它的PID不会立马消除,如果僵尸进程多了,PID还被占用着,如果操作系统再开启新的进程的话可能就起不来,在父进程一直不死的情况下是有害的。

所谓孤儿进程:就是子进程还没有执行完,主进程就已经死掉的了,但是子进程是无害的,此时子进程的PID由init进程去回收。

Process对象的其他属性和方法


join()方法,主进程等到子进程完成之后再去执行

在主进程运行过程中,如果想要并发的执行任务,我们可以开启子进程,此时主进程的任务和子进程的任务分两种情况:

1.在主进程的任务与子进程的任务彼此独立的情况下,主进程的任务先执行完毕后,主进程还需要等待子进程执行完毕,然后统一回收资源。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/942b8ff73ff4d41252705a0d573d82eb.html