python——多线程与线程锁
一、概念:
进程:对系统过来说,一个任务是一个进程;
线程:线程是包含在进程中。进程中,线程来工作,线程是最小的单位。一个进程可以启多个线程
二、进程和线程使用时的选择:
1.cpu密集型任务,用进程 #比如排序、计算的功能
2.IO密集型任务,多线程 input Output #读写频繁,网络IO或者磁盘IO。浪费CPU比较少的用多线程
3.如果需要读写也需要计算,就用多进程+多线程
# print(os.cpu_count()) #查看电脑cpu有几个
#cpu是8核,就只能同时运行8个任务
#python中GIL,全局解释器锁,导致python得多线程利用不了多核CPU,但是多进程可以
三、多线程
import threading #引入多线程 import request,time,os def lajifenlei(): time.sleep(2): print('干垃圾') start_time=time.time() def shangke(): time.sleep(2) print('上课') #单线程 for i in range(10): lajifenlei() print(time.time()-start_time) #结果:单线程需要20多秒
#启动线程 for i in range(10):#启动10个线程 th=threading.Thread(target=laijifenlei) #只写函数名 th.start() print(time.time()-start_time) #这里打印出的结果,是主线程运行完的时间,但是子线程并没有运行完。
线程和线程之间是独立的,所有的进程中,本身就有一个线程,这个线程是主线程。python文件本身就是一个进程,所以在没有启动线程的时候,本身就有一个主线程。
那么,如果需要知道所有线程运行完的时间,就需要主线程等待子线程。
主线程等待子线程方法一:
threads=[]: for i in range(10):#启动10个线程 sk=threading.Thread(target=shangke) sk.start() threads.append(sk)#运行完的子线程,加入到list中 for t in threads: t.join() #等待list中子线程全部运行完,这里的join区别于字符串的join
#t.join的作用就是,主线程一直等待全部的子线程结束之后,主线程自身才结束,程序退出。
print(time.time()-start_time) #结果:10个线程需要2秒多点
主线程等待子线程方法二:
for i in range(10): sk=threading.Thread(target=shangke) sk.start() #threading.activeCount():#查看当前运行的线程数,包括主线程 while threading.activeCount()!=1: #查看当前有几个线程,=1说明只有一个主线程,即子线程都运行完了。 pass print(time.time() - start_time)
四、线程锁:
多个线程同时操作一个数据的时候,就应该加锁
给线程加锁:
count=0 lock=threading.Lock() #申请一把锁 def lajifenlei(): global count lock.acquire()#加锁 count+=1 lock.release()#解锁。如果只加锁,不解锁,就是死锁。死锁得话,程序就会卡在这里无法继续运行 print('干垃圾') for i in range(10): jlj=threading.Thread(target-lajifenlei) jlj.start() while threading.activeCount()!=1: pass print(count) print('finash')