python3多線程的運用


Python3線程

很大一堆數據需要處理,加速效率使用多線程可以節省運算的時間。

多線程基礎

  • threading.active_count() 目前多少個激活的線程

  • threading.enumerate() 枚舉當前正在運行的多線程

  • threading.current_thread() 當前程序運行的進程是哪個線程

  • 基本用法

  target  : 指定 這個線程去哪個函數里面去執行代碼

  args:     指定將來調用 函數的時候   傳遞什么數據過去

                  args參數指定的一定是一個元組類型
 name屬性是命名多線程的名字 
 start()是開始執行多線程
 join()是線程結束后再執行后來的語句才會用到

示例代碼:

thread = threading.Thread(target=thread_job,)
thread.start()

thread_job函數是輸出一個當前正在運行的線程名稱,完整代碼。

import threading

#def main():
#    print(threading.active_count())
#    print(threading.enumerate()) # see the thread list
#    print(threading.current_thread())

def thread_job():
    print('This is a thread of %s' % threading.current_thread())

def main():
    thread = threading.Thread(target=thread_job,)
    thread.start()
if __name__ == '__main__':
    main()

join應用

想要等待所有多線程運行完畢后再顯示出all done\n,才需要用到join語句。

import threading
import time
def thread_job():
    print('T1 start\n')
    for i in range(10):
        time.sleep(0.1)
    print('T1 finish\n')

def T2_job(temp):
    print('T2 start\n')
    print("-----in test2 temp=%s-----"% str(temp))
    print('T2 finish\n')
    
def main():
    added_thread = threading.Thread(target=thread_job, name='T1')
    thread2 = threading.Thread(target=T2_job, args=(g_nums,), name='T2')
    added_thread.start()
    thread2.start()
    thread2.join()
    added_thread.join()

    print('all done\n')

if __name__ == '__main__':
    main()

Queue應用

多線程的結果是沒有返回值的,可以把所有線程結果放到長隊列中運算然后再取出來。


import threading
import time
from queue import Queue

def job(l,q):                # 執行函數
    for i in range(len(l)):
        l[i] = l[i]**2
    q.put(l)                 # 把結果加入到隊列中

def multithreading():
    q = Queue()
    threads = []
    data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
    for i in range(4):       # 定義4個線程
        t = threading.Thread(target=job, args=(data[i], q))
        t.start()
        threads.append(t)
    for thread in threads:
        thread.join()        # 結束后再執行接下來的內容
    results = []
    for _ in range(4):       # 從4個線程里面得到結果,按順序拿出結果
          results.append(q.get())
    print(results)

if __name__ == '__main__':
    multithreading()

GIL

Python不是真正意義上的多線程而是在多個線程中快速切換。

import threading
from queue import Queue
import copy
import time

def job(l, q):
    res = sum(l)
    q.put(res)

def multithreading(l):
    q = Queue()
    threads = []
    for i in range(4):
        t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
        t.start()
        threads.append(t)
    [t.join() for t in threads]
    total = 0
    for _ in range(4):
        total += q.get()
    print(total)

def normal(l):
    total = sum(l)
    print(total)

if __name__ == '__main__':
    l = list(range(1000000))
    s_t = time.time()
    normal(l*4)
    print('normal: ',time.time()-s_t)
    s_t = time.time()
    multithreading(l)
    print('multithreading: ', time.time()-s_t)

lock

第一個線程處理完結果,然后第二個線程用的時候。會用到鎖,在第一個線程處理時,第二個線程暫時無法操作。等第一個線程執行完畢之后才可以接下來的操作。

A是一個全局變量,當兩個線程對同一個變量進行操作。那么就在操作A的時候鎖住其他線程。然后當操作完畢之后再讓第二個線程操作。

import threading

def job1():
    global A, lock     # 開始鎖線程
    lock.acquire()
    for i in range(10):
        A += 1
        print('job1', A)
    lock.release()     # 釋放鎖

def job2():
    global A, lock
    lock.acquire()
    for i in range(10):
        A += 10
        print('job2', A)
    lock.release()

if __name__ == '__main__':
    lock = threading.Lock()
    A = 0
    t1 = threading.Thread(target=job1)
    t2 = threading.Thread(target=job2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

參考

https://www.bilibili.com/video/av16944429/?p=5

https://github.com/MorvanZhou/tutorials/tree/master/threadingTUT


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM