一、概念:
进程:对系统过来说,一个任务是一个进程;
线程:线程是包含在进程中。进程中,线程来工作,线程是最小的单位。一个进程可以启多个线程
二、进程和线程使用时的选择:
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')