线程
创建线程的两种方式
什么是线程呢?在另一个博客中已经介绍了,现在介绍创建线程的两种方式,只要我们会创建进程的两种方式,那么线程的创建也不会太难的,也都是大差不差
from threading import Thread
import time
def task(name):
print(f'{name} 我又回来了')
time.sleep(1)
print(f'{name} 我走了')
if __name__ == '__main__':
t=Thread(target=task,args=('zc',))
t.start()
print('主')
from threading import Thread
import time
class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print(f'{self.name}1')
time.sleep(1)
print(f'{self.name}2')
if __name__ == '__main__':
t=MyThread('zc')
t.start()
print('主')
tcp并发实现的效果
import socket
from threading import Thread
from multiprocessing import Process
"""
服务端
1.要有固定的IP和PORT
2.24小时不间断提供服务
3.能够支持并发
"""
server =socket.socket() # 括号内不加参数默认就是TCP协议
server.bind(('127.0.0.1',8080))
server.listen(5)
# 将服务的代码单独封装成一个函数
def talk(conn):
# 通信循环
while True:
try:
data = conn.recv(1024)
# 针对mac linux 客户端断开链接后
if len(data) == 0: break
print(data.decode('utf-8'))
conn.send(data.upper())
except ConnectionResetError as e:
print(e)
break
conn.close()
# 链接循环
while True:
conn, addr = server.accept() # 接客
# 叫其他人来服务客户
# t = Thread(target=talk,args=(conn,))
t = Process(target=talk,args=(conn,))
t.start()
"""客户端"""
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
client.send(b'hello world')
data = client.recv(1024)
print(data.decode('utf-8'))
线程的join方法
线程对象的join方法,就是让主线程等待子线程,子线程运行结束后再执行主线程。
from threading import Thread
import time
def task(name):
print('%s is running'%name)
time.sleep(3)
print('%s is over'%name)
if __name__ == '__main__':
t = Thread(target=task,args=('egon',))
t.start()
t.join() # 主线程等待子线程运行结束再执行
print('主')
多线程共享数据
多线程和多进程不一样,多进程之间的数据是共享的,不需要借助任何的第三方,因为在同一个进程下的多个线程共享数据。
from threading import Thread
import time
money = 100
def task():
global money
money = 666
print(money)
if __name__ == '__main__':
t = Thread(target=task)
t.start()
t.join()
print(money)
线程对象属性及其他方法
# 线程对象的
# native_id 获取当前对象的线程id
from threading import Thread, active_count, current_thread
# sctive_count() 获取当前存活的线程数
# current_thread() 获取当前线程对象,
# current_thread().name 当前对象的没名字等
# 补充:
active_count 等同于 currentThread,
current_thread 等同于 activeCount
守护线程
无论是线程还是进程,都要遵循xxx会等待主xxx运行完毕之后销毁
强调:运行完毕并非终止运行
-
对于主进程来说,运行完毕是主进程代码运行完毕
-
对于主线程来说,运行完毕指的是主线程所在的进程内的所有非主线程统统运行完毕,主线程才算运行完毕
-
详解:主进程在其代码结束后就已经算运行完毕了(守护进程在此时就会被收回),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则就会产生僵尸进程),才会结束
-
主线程是在其他非守护线程运行完毕后才算完毕(守护线程在此时就会回收)。因为主线程的结束意味着进程的结束,进程的整体资源都将被回收,而进程必须保证非守护线程都运行结束后才能结束。
from threading import Thread import time def sayhi(name): time.sleep(2) print('%s say hello' %name) if __name__ == '__main__': t=Thread(target=sayhi,args=('egon',)) t.setDaemon(True) #必须在t.start()之前设置 t.start() print('主线程') print(t.is_alive()) ''' 主线程 True ''' 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 '''线程互斥锁
from threading import Thread,Lock import time money = 100 mutex = Lock() def task(): global money mutex.acquire() tmp = money time.sleep(0.1) money = tmp - 1 mutex.release() if __name__ == '__main__': t_list = [] for i in range(100): t = Thread(target=task) t.start() t_list.append(t) for t in t_list: t.join() print(money)GIL全局解释器锁

浙公网安备 33010602011771号