三、python并发编程之多线程
一、线程理论:
1、什么是线程?
线程指的是一条流水线的工作过程。
进程根本不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位。
2、进程VS线程:
1)同一进程内的线程们共享该进程内资源
2)不同进程内的线程资源肯定是隔离的。
3)创建线程的开销比创建进程要小的多。
3、为何要用多线程?
1)多线程共享一个进程的地址空间
2)线程比进程更轻量级,线程比进程更容易创建,在许多操作系统中,创建一个线程比创建一个进程要快10-100倍,
在有大量线程需要动态和快速修改时,这一特性很有用。
3)若是多个线程都是计算密集型,这时使用多线程并不能获得性能上的增强,但如果时 IO密集型时,则会加快程序的执行速度。
4)在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小的多。(但这一条并不使用于python)
二、线程的使用:
1、开启线程的两种方式
from threading imoprt Thread
开启线程的两种方式
2、进程VS线程
进程时一个资源单位
线程才是真正的执行单位
一个进程必须有至少一个线程
1)PID
PID
2)线程创建开销小
3)同一个进程内的多个线程共享该进程内的资源
from threading import Thread import time x=1000 def task(): global x print(x) x=0 time.sleep(1) if __name__ == '__main__': t=Thread(target=task) #线程开启速度比进程快 t.start() # t.join() print('主进程。。',x)
3、线程对象的其它方法
from threading import Thread,current_thread,active_count,enumerate import time x=1000 def task(name): print('%s is runing'%name) time.sleep(3) if __name__ == '__main__': t=Thread(target=task,args=('egon',)) t.start() print(enumerate()) #查看线程 print(active_count()) #查看有几个线程,主进程也是一个线程 print('主进程。。',current_thread().name) #查看主进程
4、守护线程
守护子线程,主线程结束则子进程结束,主线程需等到所有非守护子线程结束才结束
from threading import Thread,current_thread,active_count,enumerate import time def task(name): print('%s is runing'%name) time.sleep(3) print('%s is runing' % name) if __name__ == '__main__': t=Thread(target=task,args=('egon',)) # t1 = Thread(target=task, args=('egon',)) t.daemon=True #守护子线程,主线程结束则子进程结束,主线程需等到所有非守护子线程结束才结束 t.start() # t1.start() print('主进程。。')
5、线性互斥锁
from threading import Thread,Lock import time x=100 mutex=Lock() #造一把锁 def task(): global x # mutex.acquire() #锁住变成串行 temp=x time.sleep(0.1) x=temp-1 # mutex.release() if __name__ == '__main__': t_1=[] for i in range(100): t=Thread(target=task) t_1.append(t) t.start () for t in t_1: t.join() print('主',x) #不加锁,并行的速度很快都是x的值都是100
6、死锁与递归锁
from threading import Thread,Lock,RLock import time # mutexA=Lock() # mutexB=Lock() mutexA=mutexB=RLock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): mutexA.acquire() print('%s 拿到了A锁' %self.name) mutexB.acquire() print('%s 拿到了B锁' %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print('%s 拿到了B锁' %self.name) time.sleep(0.1) mutexA.acquire() print('%s 拿到了A锁' %self.name) mutexA.release() mutexB.release() if __name__ == '__main__': for i in range(10): t=MyThread() t.start() # t1=MyThread() # t1.start() # # t2=MyThread() # t2.start() # # t3=MyThread() # t3.start() print('主')
7、信号量
from threading import Thread,Semaphore,current_thread import time,random sm=Semaphore(5) #一次只放五个位置 def go_wc(): sm.acquire() print('%s 上厕所ing' %current_thread().getName()) time.sleep(random.randint(1,3)) sm.release() if __name__ == '__main__': for i in range(23): t=Thread(target=go_wc) t.start()
即将秃头的程序员

浙公网安备 33010602011771号