# 通信任务
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.在主进程的任务与子进程的任务彼此独立的情况下,主进程的任务先执行完毕后,主进程还需要等待子进程执行完毕,然后统一回收资源。