python 之 Threading 多线程

参考视频:莫烦python https://mofanpy.com/tutorials/python-basic/threading/why/

1.多线程简单介绍

# -*- coding: utf-8 -*-
import threading

def main():
    print(threading.active_count()) #运行的线程个数
    print(threading.enumerate()) #运行的是哪些线程
    print(threading.current_thread()) #当下运行的是哪个线程

if __name__ == 'main':
    main()

6
[<_MainThread(MainThread, started 13824)>, <Thread(Thread-4, started daemon 1452)>, <Heartbeat(Thread-5, started daemon 14768)>, <HistorySavingThread(IPythonHistorySavingThread, started 4796)>, <ParentPollerWindows(Thread-3, started daemon 1852)>, <GarbageCollectorThread(Thread-6, started daemon 992)>]
<_MainThread(MainThread, started 13824)>

2.添加多线程

# -*- coding: utf-8 -*-
import threading

def thread_job():
    print('This is an added Theard,number is %s' % threading.current_thread())

def main():
    added_thread = threading.Thread(target=thread_job)
    added_thread.start()

if __name__ == 'main':
    main()

This is an added Theard,number is <Thread(Thread-10, started 8780)>

3. join 功能

# -*- coding: utf-8 -*-
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 main():
    added_thread = threading.Thread(target=thread_job,name="T1")
    added_thread.start()
    print("all done\n")

if __name__ == 'main':
    main()

T1 start

all done

T1 finish

可以看出,all done 在 T1 finish 之前,多个线程是同时执行的。要想让  all done 输出在  T1 finish 后面,可以用 joint。

# -*- coding: utf-8 -*-
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 main():
    added_thread = threading.Thread(target=thread_job,name="T1")
    added_thread.start()
    added_thread.join()
    print("all done\n")

if __name__ == 'main':
    main()

T1 start

T1 finish

all done

再一个例子

# -*- coding: utf-8 -*-
import threading
import ti
def
thread_job(): print("T1 start\n") for i in range(10): time.sleep(0.1) print("T1 finish\n") def thread_job2(): print("T2 start\n") print("T2 finish\n") def main(): added_thread = threading.Thread(target=thread_job,name="T1") added_thread2 = threading.Thread(target=thread_job2,name="T2") added_thread.start() added_thread2.start() #added_thread.join()
   #added_thread2.join()
print("all done\n") if __name__ == 'main': main()

T1 start

T2 start

T2 finish

all done

T1 finish

有了 added_thread.join() 以后,输出变为

T1 start

 

T2 start

 

T2 finish

 

T1 finish

 

all done

4. Queue 功能

用于装多线程的运算结果 

# -*- coding: utf-8 -*-

import threading
from queue import Queue

def job(l,q):
    for i in range(len(l)):
        l[i] = l[i]**2
    q.put(l) #将计算结果放入q,不能用return
    
def multiThreading():
    q = Queue()
    threads=[] #装四个线程
    data = [[1,2,3],[4,5,6],[6,6,6],[8,8,8]]
    
    for i in range(4):#分别运行四个线程并传入参数
        t = threading.Thread(target=job,args=(data[i],q)) 
        t.start()
        threads.append(t)
        
    for thread in threads:
        thread.join()
        
    results=[] #将结果一个个取出到 results 并输出
    for _ in range(4):
        results.append(q.get())
    print(results)
        
    
if __name__=="__main__":
    multiThreading()    

[[1, 4, 9], [16, 25, 36], [36, 36, 36], [64, 64, 64]]

5. 多线程控制 GIL

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)

1999998000000
normal: 0.15854287147521973
1999998000000
multithreading: 0.14863324165344238

 

 

 

 

6. 锁 lock

如果没有锁

 

import threading

def job1():
    global A
    for i in range(10):
        A+=1
        print('job1',A)

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

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

 

job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 8010
job2 90
job2 100
job2 110

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()

job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110

 

posted on 2021-08-26 12:27  蔡军帅  阅读(223)  评论(0编辑  收藏  举报