協程

windows:python

當建立進程時,會將當前py文件由上到下從新執行一次,因此咱們要將執行代碼放在__ main __ 中。linux

linux:程序員

在linux系統中,會直接複製一分代碼去執行windows

這裏有解決問題的辦法:
國內:開源中國,CSDN, cnblods,https://www.v2ex.com/安全

國外:Stack Overflow多線程

GIL: 全局解釋器鎖併發

Cpython的內存管理不是線程安全,在同一進程開啓的多線程,同一時刻只能有一個線程執行,沒法利用多核優點函數

GIL全局解釋鎖,本質上就是一把互斥鎖,保證數據的安全spa

GIL全局解釋器的優缺點:操作系統

1.優勢:

保證數據的安全

2.缺點:

單個進程下,開啓多個線程,犧牲執行效率,沒法實現並行,只能實現併發

,只能實現併發。

IO密集型,多線程

計算密集型,多進程

io密集型任務,每一個任務4s

單核:

開啓的線程比進程節省資源

多核:

多線程:

開啓4個子線程:16s

多進程:

開啓4個進程:16s + 申請開啓資源消耗的時間

計算密集型任務,每一個任務4s

單核:

開啓線程比進程節省資源

多核:

多線程:

開啓4個子線程:16s

多進程:

開啓多個進程:4s

什麼是協程?

進程:資源單位

線程:執行單位

協程: 單線程下實現併發

在io密集的狀況下,使用協程能提升最高效率

ps:協程不是任何單位,只是一個個程序員臆想出來的東西

協成的目的是爲了:

手動實現‘遇到io切換+保存狀態’去欺騙操做系統,讓操做系統誤覺得沒有io操做,將cpu的執行權限給你

from gevent import monkey  # 猴子補丁
monkey.patch_all()  # 監聽全部的任務是否有io操做
from gevent import spawn  # 任務
from gevent import joinall
import time


def task1():
    print('start from task1...')
    time.sleep(1)
    print('end from task1...')


def task2():
    print('start from task2...')
    time.sleep(2)
    print('end from task2...')


def task3():
    print('start from task3...')
    time.sleep(3)
    print('end from task3...')


if __name__ == '__main__':
    start_time = time.time()
    sp1 = spawn(task1)
    sp2 = spawn(task2)
    sp3 = spawn(task3)
    # sp1.start()
    # sp2.start()
    # sp3.start()
    # sp1.join()
    # sp2.join()
    # sp3.join()
    joinall([sp1, sp2, sp3])

    end_time = time.time()

    print(f'消耗時間:{end_time - start_time}')

    start from task1...
start from task2...
start from task3...
end from task1...
end from task2...
end from task3...
消耗時間:3.0070078372955322
線程池與進程池中的回調函數的使用:
# from gevent import monkey;monkey.patch_all()
# from gevent import spawn
# import time
#
#
# def task1(name):
#     print(name)
#     print('start')
#     time.sleep(1)
#     print('end')
#
#
# def task2():
#     print('start')
#     time.sleep(3)
#     print('end')
#
#
# def task3():
#     print('start')
#     time.sleep(5)
#     print('end')
#
# if __name__ == '__main__':
#     spawn(task1, 'tank')
#     spawn(task2)
#     g = spawn(task3)
#     g.join()


# 線程池與進程池
# 進程池
# from concurrent.futures import ProcessPoolExecutor
# import time
# # 池子對象: 內部能夠幫你提交50個啓動進程的任務
# p_pool = ProcessPoolExecutor(50)
#
#
# def task1(n):
#     print(f'from task1...{n}')
#     time.sleep(10)
#
#
# if __name__ == '__main__':
#     n = 1
#     while True:
#         # 參數1: 函數名
#         # 參數2: 函數的參數1
#         # 參數3: 函數的參數2
#         # submit(參數1, 參數2, 參數3)
#         p_pool.submit(task1, n)
#         n += 1


# 線程池
# from concurrent.futures import ThreadPoolExecutor
# import time
# # 池子對象: 內部能夠幫你提交50個啓動進程的任務
# p_pool = ThreadPoolExecutor(50)
#
#
# def task1(n):
#     print(f'from task1...{n}')
#     time.sleep(10)
#
#
# if __name__ == '__main__':
#     n = 1
#     while True:
#         # 參數1: 函數名
#         # 參數2: 函數的參數1
#         # 參數3: 函數的參數2
#         # submit(參數1, 參數2, 參數3)
#         p_pool.submit(task1, n)
#         n += 1


# add_done_callback
# from concurrent.futures import ThreadPoolExecutor
# import time
# # 池子對象: 內部能夠幫你提交50個啓動進程的任務
# p_pool = ThreadPoolExecutor(50)
#
#
# def task1(n):
#     print(f'from task1...{n}')
#     time.sleep(5)
#     return 'tank'
#
#
# def get_result(obj):
#     # print(obj.__dict__)
#     # print(obj._result)
#     result = obj.result()
#     print(result)
#
#
# if __name__ == '__main__':
#     n = 1
#     while True:
#         # 參數1: 函數名
#         # 參數2: 函數的參數1
#         # 參數3: 函數的參數2
#         # submit(參數1, 參數2, 參數3)
#         # add_done_callback(參數1),會將submit提交的task1執行的結果,傳給get_result中的第一個參數,第一個參數是一個對象。
#         p_pool.submit(task1, n).add_done_callback(get_result)
#         n += 1
相關文章
相關標籤/搜索