python中的多线程_Python中的多线程

1、什么是线程

进程其实不是一个执行单位,进程是一个资源单位

每个进程内自带一个线程,线程才是CPU上的执行单位

如果把操作系统比喻为一座工厂

在工厂内每造出一个车间===》启动一个进程

每个车间内至少有一条流水线===》每个进程内至少有一个线程

线程==》单指代码的执行过程

进程==》资源的申请与销毁的过程

2、进程VS线程

1)内存共享or隔离

多个进程内存空间彼此隔离

同一进程下的多个线程共享该进程内的数据

2)创建速度

造线程的速度要远远快于造进程

一、开启线程的两种方式(重点)

方式一:导入Thread模块

1 from threading importThread2 importtime3

5 deftask(name):6 print('%s is running' %name)7 time.sleep(3)8 print('%s is done' %name)9 if __name__ == '__main__':10 t=Thread(target=task,args=('子线程',))11 t.start()12 print('主')

方式二:创建类继承Thread

1 from threading importThread2 importtime3

4

6 #class Mythread(Thread):

7 #def run(self):

8 #print('%s is running' %self.name)

9 #time.sleep(3)

10 #print('%s is done' %self.name)

11 #12 #if __name__ == '__main__':

13 #t=Mythread()

14 #t.start()

15 #print('主')

二、线程VS进程(重点)

1 #from threading import Thread

2 #from multiprocessing import Process

3 #import time

4 #5 #def task(name):

6 #print('%s is running' %name)

7 #time.sleep(3)

8 #print('%s is done' %name)

9 #10 #if __name__ == '__main__':

11 #t=Thread(target=task,args=('子线程',))

12 ## t=Process(target=task,args=('子进程',))

13 #t.start()

14 #print('主')

线程运行结果:

da9744cc7a6a50262b567de87645dc23.png

进程运行结果:

d2c6b2ac61b3bf27f54646b60eebd489.png

2)同一进程下的多个线程共享该进程内的数据(了解知识点)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #from threading import Thread

2 #import time

3 #4 #x=100

5 #def task():

6 #global x

7 #x=0

8 #9 #if __name__ == '__main__':

10 #t=Thread(target=task,)

11 #t.start()

12 ## time.sleep(3)

13 #t.join()

14 #print('主',x)

View Code

3)查看pid(了解知识点)

注意:一个进程中的子线程pid相同

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread2 importtime,os3

4 deftask():5 print(os.getpid())6

7 if __name__ == '__main__':8 t=Thread(target=task,)9 t.start()10 print('主',os.getpid())

View Code

三、线程对象的其他方法和属性(熟悉知识点)

1)主进程等子进程是因为主进程要给子进程收尸

2)进程必须等待其内部所有线程都运行完毕才结束

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #from threading import Thread

2 #import time

3 #4 #def task(name):

5 #print('%s is running' %name)

6 #time.sleep(3)

7 #print('%s is done' %name)

8 #if __name__ == '__main__':

9 #t=Thread(target=task,args=('子线程',))

10 #t.start()

11 #print('主')

12 #

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread,current_thread,active_count,enumerate2 importtime3

4

5 deftask():6 print('%s is running' %current_thread().name)7 time.sleep(3)8 print('%s is done' %current_thread().name)9

10

11 if __name__ == '__main__':12 t = Thread(target=task,name='xxx')13 t.start()14 #t.join()

15 #print(t.is_alive())

16 #print(t.getName())

17 #print(t.name)

18 #print('主',active_count())

19 #print(enumerate())

20

21 #t.join()

22 current_thread().setName('主线程')23 print('主',current_thread().name)

View Code

四、守护线程(熟悉知识点)

守护线程(daemon)会在本进程内所有非守护的线程都死掉了才跟着死

即:

守护线程其实守护的是整个进程的运行周期(进程内所有的非守护线程都运行完毕)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #from threading import Thread,current_thread

2 #import time

3 #4 #5 #def task():

6 #print('%s is running' % current_thread().name)

7 #time.sleep(3)

8 #print('%s is done' % current_thread().name)

9 #10 #11 #if __name__ == '__main__':

12 #t = Thread(target=task,name='守护线程')

13 #t.daemon=True

14 #t.start()

15 #print('主')

守护进程

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread2 importtime3 deffoo():4 print(123)5 time.sleep(3)6 print("end123")7

8 defbar():9 print(456)10 time.sleep(1)11 print("end456")12

13

14 t1=Thread(target=foo)15 t2=Thread(target=bar)16

17 t1.daemon=True18 t1.start()19 t2.start()20 print("main-------")21

22 '''

23 12324 45625 main-------26 end45627

28 '''

较迷惑人的守护进程

五、互斥锁(熟悉知识点)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread,Lock2 importtime3

4 mutex=Lock()5

6 x=100

7 deftask():8 globalx9 #mutex.acquire()

10 temp=x11 time.sleep(0.1)12 x=temp-1

13 #mutex.release()

14

15 if __name__ == '__main__':16 t_l=[]17 start=time.time()18 for i in range(100):19 t=Thread(target=task)20 t_l.append(t)21 t.start()22

23 for t int_l:24 t.join()25

26 stop=time.time()27 print(x,stop-start)

互斥锁

六、死锁现象与递归锁(熟悉知识点)

如果用Lock(互斥锁),会发生死锁现象

递归锁本质是一把锁,可连续acqruie,但只有其上的计数为0时其他线程才可对其调用

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread,Lock,active_count,RLock2 importtime3

4 #mutexA=Lock()

5 #mutexB=Lock()

6 obj=RLock() #递归锁的特点:可以连续的acquire

7 mutexA=obj8 mutexB=obj9

10 classMythread(Thread):11 defrun(self):12 self.f1()13 self.f2()14

15 deff1(self):16 mutexA.acquire()17 print('%s 拿到A锁' %self.name)18

19 mutexB.acquire()20 print('%s 拿到B锁' %self.name)21 mutexB.release()22

23 mutexA.release()24

25 deff2(self):26 mutexB.acquire()27 print('%s 拿到B锁' %self.name)28 time.sleep(1)29

30 mutexA.acquire()31 print('%s 拿到A锁' %self.name)32 mutexA.release()33

34 mutexB.release()35

36 if __name__ == '__main__':37 for i in range(10):38 t=Mythread()39 t.start()40 #print(active_count())

View Code

七、信号量(熟悉知识点)

信号量本质上还是锁,但区别信号量是控制同一时刻并发执行的任务数

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 from threading importThread,Semaphore,current_thread2 importtime,random3

4 sm=Semaphore(5)5

6 deftask():7 with sm:8 print('%s 正在上厕所' %current_thread().name)9 time.sleep(random.randint(1,4))10

11

12 if __name__ == '__main__':13 for i in range(20):14 t=Thread(target=task)15 t.start()

信号量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值