python 多進程+多線程,多進程+協程 代碼示例

此方法 可以在 flask+gunicorn 設置的服務中使用,注意 開發時,使用命令行方式啓動服務,不要使用Pycharm(會崩潰);

 

  • 多進程+多線程
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from multiprocessing import Pool


class ProcessThread:
    def post(self):
        """
        多進程和線程配合使用示例
        """

        # 多進程 執行 fun_thread
        pool = Pool(5)
        lst = [1, 2, 3]
        res = pool.map(self.fun_thread, lst)
        pool.close()
        pool.join()
        print(res, "多進程 返回 的 所有線程及 每個線程執行函數的結果")

        print("執行其他任務")

    def fun_thread(self, num):
        """
        多線程執行 函數
        as_completed 有一個線程返回結果就返回一個結果,不用等到所有線程都返回
        :param num:
        :return:
        """
        result_list = []
        pool = ThreadPoolExecutor()
        pool_result = [pool.submit(self.intensive, n, id) for n, id in [(1, "a",), (3, "b",), (2, "c",), (2, "d",)]]
        for result in as_completed(pool_result):
            # 注意 調用 result.result()
            item = result.result()
            result_list.append(item)
            if len(result_list) == 2:
                break
        print(f"線程 {num} 執行的結果爲:{result_list}")
        return result_list

    def intensive(self, n, id):
        """
        實際調用的方法
        :param n:
        :param id:
        :return:
        """
        time.sleep(n)
        print("每個函數執行的結果", n, id)
        return "task", n


if __name__ == "__main__":
    ProcessThread().post()

 

  • 多進程+協程
#!/usr/bin/env python3
# coding: utf-8
"""
多進程和協程配合使用示例
"""
from multiprocessing import Process

import gevent
from gevent import monkey
from gevent.pool import Group

monkey.patch_all()


class TestProgram(object):  # 測試程序

    def intensive(self, n):
        """
        協程函數
        :param n:
        :return:
        """
        gevent.sleep(n)
        print(f'協程函數執行完成,耗時{n}')
        return "task", n

    def fun_one(self):
        igroup = Group()
        result_list = []
        for i in igroup.imap_unordered(self.intensive, [3, 2, 1]):
            result_list.append(i)
            if len(result_list) == 2:
                break
        print(f"第1個進程函數 執行完成{result_list}")
        return "111"

    def fun_two(self):
        igroup = Group()
        result_list = []
        for i in igroup.imap_unordered(self.intensive, [4, 1.4, 1.1]):
            result_list.append(i)
            if len(result_list) == 2:
                break
        print(f"第2個進程函數 執行完成{result_list}")
        return "222"

    def fun_three(self):
        igroup = Group()
        result_list = []
        for i in igroup.imap_unordered(self.intensive, [3.2, 2.3, 1.6]):
            result_list.append(i)
            if len(result_list) == 2:
                break
        print(f"第3個進程函數 執行完成{result_list}")
        return "333"

    def main(self):
        """
        使用多進程執行程序
        :return:
        """
        p_lst = []
        p1 = Process(target=self.fun_one, args=(2,))
        p_lst.append(p1)
        p1.start()

        p2 = Process(target=self.fun_two, args=(3,))
        p_lst.append(p2)
        p2.start()

        p3 = Process(target=self.fun_three, args=(4,))
        p_lst.append(p3)
        p3.start()

        for p in p_lst:
            p.join()
            print('進程執行結束', p)
        print("開始其他任務")


TestProgram().main()  # 啓動主程序,它會開啓3個進程。

協程 中的 gevent 在協程間自動進行切換,注意使用時 開頭添加 monkey.patch_all()  才能自動進行切換,比如  time.sleep(3) 和 gevent.time.sleep(3) ; 如果 沒有添加 monkey.patch_all()則 time.sleep(3)沒有效果,無法自動切換協程;

 

相關鏈接:

python 協程庫gevent學習--gevent數據結構及實戰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章