线程

一、线程

1.什么是线程?

首先我们要知道,进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物

进程:资源单位

线程:执行单位

将内存比喻成工厂

那么进程就相当于是工厂里面的车间

而你的线程就相当于是车间里面的流水线

ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中提供代码运行所需要的资源

2.为什么要有线程

开进程

  1.申请内存空间 耗资源

     2.“拷贝代码” 耗资源

开线程

  一个进程内可以起多个线程,并且线程与线程之间数据是共享的

PS:开启线程的开销要远小于开启进程的开销

二、创建进程的两种方式

  方式一:

 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 over'%name)
 8 
 9 #开线程不需要在__main__代码块中,但是出于习惯,我们可以写在__main__代码块中
10 t = Thread(target=task,args=('jason',))
11 t.start() #告诉操作系统开辟一个线程
12 #小的代码执行完,线程就已经开启了
13 print('')

  方式二:

 1 from threading import Thread
 2 import time
 3 
 4 class MyThread(Thread):
 5     def __init__(self,name):
 6         super().__init__()
 7         self.name = name
 8 
 9     def run(self):
10         print('%s is running'%(self.name))
11         time.sleep(3)
12         print('%s is over'%(self.name))
13 
14 t = MyThread('jason')
15 t.start()
16 print('')

三、线程对象及其他方法

 1 from threading import Thread,current_thread,active_count
 2 import os
 3 import time
 4 
 5 def task(name,i):
 6     print('%s is running'%name)
 7     print('字current_thread:',current_thread().name)
 8     print('',os.getpid())
 9     time.sleep(i)
10     print('%s is over'%name)
11 
12 t = Thread(target=task,args=('jason',1))
13 t1 = Thread(target=task,args=('tank',2))
14 t.start()
15 t1.start()
16 t1.join() #主线程等待子线程运行完毕
17 print('当前正在活跃的线程数',active_count())
18 print('')
19 print('主current_thread:',current_thread().name)
20 print('',os.getpid())

四、守护线程

 1 from threading import Thread,current_thread
 2 import time
 3 
 4 def task(i):
 5     print(current_thread().name)
 6     time.sleep(i)
 7     print('GG')
 8 
 9 t = Thread(target=task,args=(1,))
10 t.daemon = True
11 t.start()
12 print('')

主线程的结束也就意味着进程的结束

主线程必须等待其他非守护线程的结束才能结束,原因是:因为子线程在运行时需要使用进程中的资源,而主线程一旦结束了资源也就销毁了

五、线程间通信

 1 from threading import Thread
 2 
 3 money = 666
 4 
 5 def task():
 6     global money
 7     money = 999
 8 
 9 t = Thread(target=task)
10 t.start()
11 t.join()
12 print(money)
13 
14 '''
15 事实证明线程与线程之间可以进行通信
16 '''

六、互斥锁

 1 from threading import Thread,Lock
 2 import time
 3 
 4 n = 100
 5 
 6 def task(mutex):
 7     global n
 8     mutex.acquire()
 9     num = n
10     time.sleep(0.1)
11     n = num - 1
12     mutex.release()
13 
14 t_list = []
15 mutex = Lock()
16 for i in range(100):
17     t = Thread(target=task,args=(mutex,))
18     t.start()
19     t.join()
20 print(n)

七、小例题及分析

 1 from threading import Thread
 2 from multiprocessing import Process
 3 import time
 4 def foo():
 5     print(123)
 6     time.sleep(1)
 7     print("end123")
 8 
 9 def bar():
10     print(456)
11     time.sleep(3)
12     print("end456")
13 
14 if __name__ == '__main__':
15     t1=Thread(target=foo)
16     t2=Thread(target=bar)
17     t1.daemon=True
18     t1.start()
19     t2.start()
20     print("main-------")

结果为:

'''
    123
    456
    main-------
    end123
    end456
'''

分析:

首先创建两个线程对象,将t1设置为守护线程,意味着主进程执行完毕后,就会一起终止t1,然后,执行t1线程,紧接着执行t2线程,所以首先打印:123,456。然后根据主线程代码打印了:main-----。此时t1暂停一秒后执行了打印:end123。t1运行结束,但是此时t2并未运行结束,所以主线程会继续等待t2线程运行结束再结束执行。3秒过后t2执行打印:end456。t2也运行结束,主线程随之终止。

原文地址:https://www.cnblogs.com/spencerzhu/p/11341963.html