python之線程相關操做

1.線程: 一個進程能夠有多個線程,共享一個進程的資源;python

2.進程線程的區別:多線程

   進程是資源分配的最小單位,線程是程序執行的最小單位app

3.python中線程模塊threading, 提供的類: Thread, Lock, Rlock, Semaphore, Event, 等等ui

4.線程的建立方式spa

複製代碼
# 第一種
# from threading import Thread
# def f1(s):
#     print('我是%s' % s)
# def f2(s):
#     print('我是%s' % s)
# 
# if __name__ == '__main__':
#     t = Thread(target=f1, args=(1,))
#     t1 = Thread(target=f1, args=(2,))
#     t.start()
#     t1.start()
#     print('我是主線程')

# 第二種
from threading import Thread

class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name
    def run(self):
        print('%s今天仍是不能皮' % self.name)
if __name__ == '__main__':
    t = MyThread('Jerry')
    t.start()
    print('主線程')
複製代碼

6.查看線程的進程id(同進程查看方式同樣)線程

複製代碼
import os
from threading import Thread
def f1(n):
    print('1號', os.getpid())
    print('%s號線程任務' % n)
def f2(n):
    print('2號', os.getpid())
    print('%s號線程任務' % n)
if __name__ == '__main__':
    t1 = Thread(target=f1, args=(1,))
    t2 = Thread(target=f2, args=(2,))
    t1.start()
    t2.start()
    print('主線程', os.getpid())
    print('主線程')
複製代碼

7. 在進程之間數據是空間隔離的, 而在線程中是數據共享的設計

複製代碼
import time
from threading import Thread

#  經過對全局變量的修改來驗證線程之間是數據共享的, 共享同一進程中的數據
num = 100
def f1():
    time.sleep(3)
    global  num
    num = 3
    print('子線程的num', num)

if __name__ == '__main__':
    t = Thread(target=f1)
    t.start()
    t.join() # 等待子線程運行結束才繼續向下執行
    print('主線程的num', num)
複製代碼

8.多進程和多線程的效率對比code

對於io密集型的, 多線程的時間較快blog

複製代碼
def f1():
    time.sleep(1)  #io密集型
    
if __name__ == '__main__':
    # 查看一下20個線程執行20個任務的執行時間
    t_s_time = time.time()
    t_list = []
    for i in range(5):
        t = Thread(target=f1,)
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    t_e_time = time.time()
    t_dif_time = t_e_time - t_s_time
    # 查看一下20個進程執行一樣的任務的執行時間
    p_s_time = time.time()
    p_list = []
    for i in range(5):
        p = Process(target=f1,)
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time
    print('多線程的執行時間:', t_dif_time)
    print('多jincheng的執行時間:', p_dif_time)
複製代碼

計算型:遞歸

複製代碼
import time
from threading import Thread
from multiprocessing import Process

def f1():
    # 計算型:
    n = 10
    for i in range(10000000):
        n = n + i
if __name__ == '__main__':
    # 查看一下20個線程執行20個任務的執行時間
    t_s_time = time.time()
    t_list = []
    for i in range(5):
        t = Thread(target=f1,)
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    t_e_time = time.time()
    t_dif_time = t_e_time - t_s_time
    # 查看一下20個進程執行一樣的任務的執行時間
    p_s_time = time.time()
    p_list = []
    for i in range(5):
        p = Process(target=f1,)
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time
    print('多線程的執行時間:', t_dif_time)
    print('多jincheng的執行時間:', p_dif_time)
複製代碼

 

 9.鎖,同步,互斥鎖 爲了保護多線成中數據的完整性和線程間狀態的同步.(同進程的鎖同樣)

 在線程鎖中, 會產生死鎖現象. 同時搶鎖

複製代碼
import time
from threading import Thread, Lock, RLock
def f1(locA, locB):
    # print('xxxx')
    # time.sleep(0.1)
    locA.acquire()
    print('f1>>1號搶到了A鎖')

    time.sleep(1)
    locB.acquire()
    print('f1>>1號搶到了B鎖')
    locB.release()

    locA.release()
def f2(locA, locB):
    print('22222')
    time.sleep(0.1)
    locB.acquire()
    print('f2>>2號搶到了B鎖')
    locA.acquire()
    time.sleep(1)
    print('f2>>2號搶到了A鎖')
    locA.release()
    locB.release()
if __name__ == '__main__':
    locA = Lock()
    locB = Lock()
    t1 = Thread(target=f1, args=(locA, locB))
    t2 = Thread(target=f2, args=(locA, locB))
    t1.start()
    t2.start()
複製代碼

  遞歸鎖解決了 死鎖現象

複製代碼
import time
from threading import Thread, Lock, RLock

def f1(locA, locB):
    print('xxxxx')
    time.sleep(0.1)
    locA.acquire()
    print('f1>>>1號搶到了A鎖')
    time.sleep(1)
    locB.acquire()
    print('f1>>>2號搶到了B鎖')
    locB.release()
    locA.release()
def f2(locA, locB):
    print('22222')
    time.sleep(0.1)
    locB.acquire()
    print('f2>>>1號搶到了A鎖')
    time.sleep(1)
    locA.acquire()
    print('f2>>>2號搶到了B鎖')
    locA.release()
    locB.release()
if __name__ == '__main__':
    locA = locB = RLock()
    t1 = Thread(target=f1, args=(locA, locB))
    t2 = Thread(target=f2, args=(locB, locA))
    t1.start()
    t2.start()
複製代碼

10.多線程的程序不結束 和 多進程的程序不結束的區別

守護進程:主進程代碼執行運行結束,守護進程隨之結束
守護線程:守護線程會等待全部非守護線程運行結束才結束
複製代碼
import time
from threading import Thread
from multiprocessing import Process


# 守護進程:主進程代碼執行運行結束,守護進程隨之結束
# 守護線程:守護線程會等待全部非守護線程運行結束才結束
def f1():
    time.sleep(2)
    print('一號線程')

def f2():
    time.sleep(3)
    print('二號線程')
def f3():
    time.sleep(2)
    print('一號進程')

def f4():
    time.sleep(3)
    print('二號進程')
if __name__ == '__main__':
    # t1 = Thread(target=f1,)
    # t2 = Thread(target=f2,)
    # # t1.daemon = True  #  等非守護線程結束,守護線程纔會結束 結果:  主線程結束  一號線程  二號線程
    # t2.daemon = True # 結果: 主線程結束      一號線程
    # t1.start()
    # t2.start()
    # print('主線程結束')
    p1 = Process(target=f3,)
    p2 = Process(target=f4,)
    # p1.daemon = True # 結果: 主進程   二號線程
    p2.daemon= True # 結果: 主進程   一號線程
    p1.start()
    p2.start()
    print('主進程')
複製代碼

11. GIL鎖 :  cpython解釋器上的一把互斥鎖, Python解釋器因爲設計時有GIL全局鎖,致使了多線程沒法利用多核

Python雖然不能利用多線程實現多核任務,但能夠經過多進程實現多核任務。多個Python進程有各自獨立的GIL鎖,互不影響。

相關文章
相關標籤/搜索