实现服务器端并发
服务器端
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 15 15:27:19 2019
@author: clt
"""
#服务器端
#为了实现并发的连接,用多线程更合适
#服务器有两个任务:1、建连接;2、收发消息
import socket
from threading import Thread,current_thread
def communicate(conn):
print('用于通信的线程:%s' %current_thread().getName()) #拿到当前线程对象
while True:
try:
data=conn.recv(1024)
if not data:
break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
def server(ip,port):
print('用于建连接的线程:%s' %current_thread().getName()) #拿到当前线程对象
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((ip,port))
server.listen(5)
while True:
conn,addr=server.accept() #主线程负责建连接
print(addr)
t=Thread(target=communicate,args=(conn,)) #每接到一个连接就建立一个线程来通信
#communicate(conn)
t.start()
server.close()
if __name__=='__main__':
server('127.0.0.1',8000)
客户端代码不用动
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 15 16:05:54 2019
@author: clt
"""
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
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()
上边的代码虽说实现了服务器的并发,但是现实中不能无限的开线程,使用线程池解决这个问题
- 守护线程
主线程的生命周期就代表了守护线程的生命周期
守护线程要等待环境中所有的非守护线程都运行完毕才完毕
#守护线程
from threading import Thread
import time
def sayhi(name):
print('===>')
time.sleep(3)
print('%s say hello' %name)
if __name__=='__main__':
t=Thread(target=sayhi,args=('egg',))
t.daemon=True
t.start()
print('主线程')
#没有僵尸线程的说法
#现在环境中会有两个线程,但是主线程之所以等待子线程,因为主线程在这里等价于主进程
#其实主线程和子线程地位平等,这里的称呼只是为了方便理解
结果:
===>
主线程
#守护进程还没来得及运行完,但是主线程运行完了,所以也就跟着终止了
两个非守护线程,一个守护线程,守护线程会等到所有的非守护线程运行完才结束
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True
t1.start()
t2.start()
print("main-------")
结果:
123
456
main-------
end123
end456