天天看點

多任務處理--多線程、多程序、協程

1.多線程

1)特點:

線程的并發是利用cpu上下文的切換(是并發,不是并行)

多線程執行的順序是無序的

多線程共享全局變量

線程是繼承在程序裡的,沒有程序就沒有線程

GIL全局解釋器鎖

隻要在進行耗時的IO操作的時候,能釋放GIL,是以隻要在IO密集型的代碼裡,用多線程就很合适

2)多任務處理執行個體

import threading

global_num = 0

lock = threading.Lock()

def test1():

    global global_num

    lock.acquire() 保證在該程序執行期間其他程序無法調用num變量

    for i in range(1000000):

        global_num += 1

    lock.release()

def test2():

    global global_num

    lock.acquire()

    for i in range(1000000):

        global_num += 1

    lock.release()

t1 = threading.Thread(target=test1)

t2 = threading.Thread(target=test2)

t1.start()

t2.start()

t1.join() 保證兩個子程序執行完成後再執行主程序

t2.join()

print(global_num)

輸出結果:

2000000

2.多程序

1)特點

一個程式運作起來之後,代碼+用到的資源稱之為程序,它是作業系統配置設定資源的基本機關,不僅可以通過線程完成多任務,程序也是可以的

程序之間是互相獨立的

cpu密集的時候适合用多程序

程序之間的資源不共享

2)多任務處理執行個體

import time

import threading

g_num = 0

def edit():

    global g_num

    for i in range(10):

        g_num += 1

def reader():

    print(g_num)

if __name__ == '__main__':

    p1 = multiprocessing.Process(target=edit)

    p2 = multiprocessing.Process(target=reader())

    p1.start()

    p2.start()

    p1.join()

    p2.join()

輸出結果:

10

3)程序池

import multiprocessing

import time

from multiprocessing import Pool

def test1():

    for i in range(10):

        time.sleep(1)

        print('task1',i)

def test2():

    for i in range(10):

        time.sleep(1)

        print('task2',i)

if __name__ == '__main__':

    pool = Pool(2)允許最大同時執行的程序數

    pool.apply_async(test1)

    pool.apply_async(test2)

    pool.close()

    pool.join()

輸出結果:

task1 0

task2 0

task1 1

task2 1

task1 2

task2 2

task1 3

task2 3

3.協程

1)特點

協程:也叫微線程,協程是在一個線程裡面的

異步IO:遇到io請求就切換

先有程序,再有線程,才能有協程

2)多任務處理執行個體

import time

import gevent

from gevent import monkey

monkey.patch_all()

def test1(n):

    for i in range(n):

        # gevent.sleep(1)

        time.sleep(1)

        print('task1',i)

def test2(n):

    for i in range(n):

        # gevent.sleep(1)

        time.sleep(1)

        print('task2',i)

g1 = gevent.spawn(test1,10)

g2 = gevent.spawn(test2,10)

g1.join()

g2.join()

輸出結果:

task1 0

task2 0

task1 1

task2 1

task1 2

task2 2

task1 3

task2 3

轉載于:https://www.cnblogs.com/Agnostida-Trilobita/p/11060513.html