什么是线程
进程其实是一个资源单位,而进程内的线程才是cpu上的执行单位
线程其实指的就是代码的执行过程
为何要用线程
线程vs进程
同一进程下的多个线程共享该进程内的资源
创建线程的开销要远远小于进程
开启线程的两种方式:
方式一:
from threading import Thread
import time
def task(name):
print('%s is running' %name)
time.sleep(2)
print('%s is done' %name)
if __name__ == '__main__':
t=Thread(target=task,args=('线程1',))
t.start()
print('主')
方式二:
from threading import Thread
import time
class Mythread(Thread):
def run(self):
print('%s is running' %self.name)
time.sleep(2)
print('%s is done' %self.name)
if __name__ == '__main__':
t=Mythread()
t.start()
print('主')
线程特性:
在该进程内 所有线程是共享资源的 所以打印的n是0 而进程间是不会共享的 进程打印的就是100
from threading import Thread
import time
n=100
def task():
global n
n=0
if __name__ == '__main__':
t=Thread(target=task)
t.start()
t.join()
print('主',n)
在主进程下开启多个线程,每个线程都跟主进程的pid一样
from threading import Thread
import time,os
def task():
print('%s is running' %os.getpid())
if __name__ == '__main__':
t=Thread(target=task)
t.start()
print('主',os.getpid())
Thread实例对象的方法
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
threading模块提供的一些方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
from threading import Thread,current_thread
import time,os
def task():
print('%s is running ' %current_thread())
time.sleep(2)
if __name__ == '__main__':
t=Thread(target=task,)
t.start()
print('主',current_thread())
from threading import Thread,active_count
import time,os
def task():
print('%s is running ' %current_thread())
time.sleep(2)
if __name__ == '__main__':
t=Thread(target=task,)
t.start()
# t.join()
print('主',active_count())
守护线程
无论是线程还是进程都遵循 守护 线程/进程 会等待主进程/线程 运行完毕后被销毁 运行完毕并非终止运行
对于主进程来说,运行完毕指的是主进程代码运行完毕
主进程在其代码结束后就已经算运行完毕了(守护进程在此时被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束
对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束
from threading import Thread
from multiprocessing import Process
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
# t1=Thread(target=foo)
# t2=Thread(target=bar)
t1=Process(target=foo)
t2=Process(target=bar)
t1.daemon=True
t1.start()
t2.start()
线程互斥锁:
线程运行速度快 0.1秒 就能并发100个线程 利用mutex=Lock() 加把锁 因为线程之前数据共享 不需要和进程一样把互斥锁传给进程
from threading import Thread,Lock
import time
mutex=Lock()
n=100
def task():
global n
mutex.acquire()
temp=n
time.sleep(0.1)
n=temp-1
mutex.release()
if __name__ == '__main__':
t_l=[]
for i in range(100):
t=Thread(target=task)
t_l.append(t)
t.start()
for t in t_l:
t.join()
print(n)