程序:指令和数据的有序集合,一个可运行文件
进程:一段程序的执行过程
进程的三种状态:就绪态,运行态,阻塞态
就绪态:获取了除CPU外的其他所有资源,只要处理器分配资源就可以立马执行
运行态:获取处理器资源,程序开始执行
阻塞态:等待条件满足才能运行的状态,如等待I/0操作
线程:通常,一个进程中包含多个线程,线程可以利用进程中的所有资源,线程作为独立运行、独立调度的基本单位,为进程
中的 一个函数;
多线程:为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率;线程是同一时间需
要完成多项任务的时候实现的;
进程与线程的区别:进程在执行过程拥有独立的内存单元,而多线程共享内存
子线程:程序执行时,程序本身就是一个线程,为主线程,手动创建的线程为子线程,主线程执行过程中,不会等待子线程
代码 | 运行结果
|
import threading import time start=time.time() def myprint(name): curstart=time.time() time.sleep(5) print(name,'线程执行了') end=time.time() print(name,'开始时间',curstart-start,'结束时间',end-start) # 程序执行时,程序本身就是一个线程,为主线程 # 手动创建的线程为子线程 # 主线程执行过程中,不会等待子线程 t1=threading.Thread(target=myprint,args=['thread1',]) t2=threading.Thread(target=myprint,args=['thread2',]) t3=threading.Thread(target=myprint,args=['thread3',]) #方法1 t1.start() t1.join() #进行线程阻塞,当t1线程执行结束后,启用t2 t2.start() t2.join() t3.start() t3.join() end=time.time() print('主线程执行完毕',end-start) #方法2 t1.start() t2.start() t3.start() t1.join() t2.join() t3.join() end=time.time() print('主线程执行完毕',end-start) | 1.每个线程启动后,紧跟着阻塞线程,相当于程序按顺序执行多个线程,效果认为单线程 程序运行总时长为:15s
thread1 线程执行了
2.先启用所有需要同时执行的线程,然后阻塞所有线程,大大节约程序运行时间,发挥多线程功能; 程序运行总时长为:5s thread1 线程执行了
|
线程锁(互斥锁):
当多个线程对统一段内存地址的数据进行修改时,会发生错乱的情况,
import threading
import time
lock=threading.Lock() #创建线程锁
num=100
def myprint(name):
lock.acquire() # 获取锁,用于线程同步
global num
num=num-1
print(name,'当前num为',num)
lock.release() # 释放锁,开启下一个线程
for i in range(100):
t1=threading.Thread(target=myprint,args=[i+1,])
t1.start()
全局解释器锁(GIL):不管系统CPU核心数量多少,都保证python程序中同一时间点只能执行一个线程,对多CPU的系统来说造成资源的浪费(python的缺点),解决方法为多进程
import time
from multiprocessing import Process #多进程包
#多进程可以实现多个任务并行,适用于多CPU
start=time.time()
def run(name):
# print(name,'执行')
time.sleep(5)
end=time.time()
print(name,'执行',end-start)
if __name__ == '__main__':
#注意多进程必须window系统,必须放在’if __name__ == '__main__':‘语句中
t1=Process(target=run,args=['t1',])
t2 = Process(target=run, args=['t2', ])
t3 = Process(target=run, args=['t3', ])
t1.start()
t2.start()
t3.start()