一、多线程模块基础使用
启动线程
使用方法一:
from threading import Thread
def func1(i):
print("我是线程%d"%i)
if __name__ == '__main__':
for i in range(10):
t = Thread(target=func1,args=(i,))
t.start()
使用方法二:
from threading import Thread
class Mythread(Thread):
def __init__(self):
super().__init__()
def run(self):
print("我是使用面向对象的方法起的线程")
t1 = Mythread()
t1.start()
其他方法
查看线程当前id和名字
- threading.current_thread()
- threading.get_ident()
查看存活的线程数量
- threading.active_count()
二、全局解释器锁GIL
CPython 在解释器进程级别有一把锁,叫做GIL,即全局解释器锁。
GIL 保证CPython进程中,只有一个线程能够进入CPU中进行执行。甚至是在多核CPU的情况下,也只允许同时只能有一个CPU 上运行该进程的一个线程
正是因为这个原因CPython无法真正执行多线程的运算
但是需要多线程的运算往往是在计算密集型的操作中,因此在编写此类应用的时候尽可能不要使用Cpython来进行编程。
在多线程的环境下,python会按照以下步骤来执行:
- 设置GIL
- 唤醒一个线程去执行代码
- 运行执行字节或者让线程主动交出控制权(可以通过sleep来进行控制)
- 让一个线程进行休眠,唤醒另一个线程
- 释放GIL
- 重复以上操作
三、多线程实现socket
服务端
from threading import Thread
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.bind(("127.0.0.1",8005))
sk.listen()
def recv_mesg(conn):
mesg = conn.recv(1024).decode("utf-8")
print(mesg)
while True:
conn, addr = sk.accept() #每一次循环都开启一个连接
t = Thread(target=recv_mesg,args=(conn,)) #启动一个线程来接收消息
t.start()
sk.close()