線程和程序
- 線程是程式執行的最小機關,而程序是作業系統配置設定資源的最小機關
- 一個程序由一個或多個線程組成,線程是一個程序中代碼的不同執行路線
- 程序之間互相獨立,但同一線程下的各個線程之間共享程式的記憶體空間(包括代碼段,資料集,堆等)及一些程序級的資源(如打開檔案和信号等),某程序内的線程在其他程序中不可見
- 線程上下文切換比程序上下文切換要快的多
建立多線程
方法1:
調用threading庫的Thread類:
def test(x):
print(x)
time.sleep(2)
t1 = threading.Thread(target=test,args=(1,))
t2 = threading.Thread(target=test,args=(2,))
t1.start()
t2.start()
方法2:
以繼承于Thread類的方式:
cLass MyThread(threading.Thread):
def__ init__ (seLf, n):
super (MyThread, seLf).__ init__()
self.n = n
def run(self):
print('以類的方式建立多線程',self.n)
time.sleep(3)
r1 = MyThread(1)
r2 = MyThread(2)
r1.start()
r2.start()
一些常用方法
檢視活動的線程數:threading.active_count()
檢視目前線程:threading.current_thread()
守護線程
使用setDaemon(True)把所有的子線程都變成了主線程的守護線程,
是以當主線程結束後,子線程也會随之結束,是以當主線程結束後,整個程式就退出了。
所謂’線程守護’,就是主線程不管該線程的執行情況,隻要是其他子線程結束且主線程執行完畢,主線程都會關閉。也就是說:主線程不等待該守護線程的執行完再去關閉
def run(n):
print('task',n)
time.sleep(2)
print('5s')
time.sleep(2)
print('3s')
time.sleep(2)
print('1s')
if __name__ == '__main__':
t=threading.Thread(target=run,args=('t1',))
t.setDaemon(True) #把子線程設定為守護線程,必須在start()之前設定
t.start()
t.join() #設定主線程等待子線程結束
print('end')
線程鎖
def work():
global n
lock.acquire()
temp = n
time.sleep(0.1)
n = temp-1
lock.release()
if __name__ == '__main__':
lock = Lock()
n = 100
l = []
for i in range(100):
p = Thread(target=work)
l.append(p)
p.start()
for p in l:
p.join()
遞歸鎖
def func(lock):
global gl_num
lock.acquire()
gl_num += 1
time.sleep(1)
print(gl_num)
lock.release()
if __name__ == '__main__':
gl_num = 0
lock = threading.RLock()
for i in range(10):
t = threading.Thread(target=func,args=(lock,))
t.start()
執行個體:
import threading
import time
class MyThread1(threading.Thread):
def run(self):
while (True):
localetime = time.asctime(time.localtime(time.time()))
print(localetime)
time.sleep(1)
class MyThread2(threading.Thread):
def __init__(self,name):
super(MyThread2, self).__init__()
self.name=name
def run(self):
for i in range(4):
print(self.name)
time.sleep(2)
if __name__ == '__main__':
mt1 = MyThread1()
mt2 = MyThread2("張三")
mt2.start()
mt1.start()