1. 程式人生 > 實用技巧 >python併發程式設計-執行緒守護程序的使用

python併發程式設計-執行緒守護程序的使用

網路高併發請求,需要不影響併發的情況下,非同步寫日誌

實驗如下

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:admin
# datetime:2020/11/17 0017 16:01
# 開執行緒
import os
import time
from threading import Thread


def task(log):
    """非同步執行的任務,無返回值
    """
    with open("log.txt", mode='a') as f:
        time.sleep(2)
        f.write(log)
        f.flush()
    print log  # 發現此處列印僅在本py檔案未關閉時,才打印


def access_run(number):
    print "訪問主程序:%s" % os.getpid()

    print "begin----》"
    print "business doing---------》"
    time.sleep(1)

    log = "使用者%s,訪問日誌" % number
    instance = Thread(target=task, args=(log,))
    instance.setDaemon(True)  # 設定守護執行緒,隨主執行緒結束而結束
    instance.start()

    print "end business is done ------》"
    return "使用者得到的響應訊息:%s" % (str(number + 1))


if __name__ == '__main__':
    start = time.time()
    """
    結論: 
    1. 開啟子執行緒處理非同步任務,想在主執行緒任務處理完,回收執行緒資源,需配置守護執行緒
    2. 如果子執行緒非同步任務耗時長,在主執行緒任務完成後,並不關心非同步任務完成否,就會關閉子執行緒
    3. 基於第2點,將導致如果主執行緒任務執行完了就停服了,將可能導致子執行緒任務不會執行,即日誌記錄任務不會執行【發現執行上面程式碼只記錄了第一次訪問的日誌】
    4. 想要解決這個,只能保證服務不掛
    應用:
    1. 不影響併發的情況下,採用開啟子執行緒記錄日誌,不會等日誌是否記錄完,就會處理其他使用者的訪問,比裝飾器需要等一次請求結束才處理其他請求,效率高
    """
    print "----------服務主程序:%s----------" % os.getpid()
    message = []
    for i in range(3):
        ret = access_run(i)
        # print ret  # 如果此處用了print,實際就是阻塞,等待結果出來後,再執行下一個任務, 總耗時3秒多
        message.append(ret)  # 如果此處僅將結果收集,不會阻塞
    print message
    print "總耗時:%s" % (time.time() - start)

    # 經測試,當上面任務執行完了,保證py檔案即主執行緒不掛, 日誌都會被記錄上
    # while 1: pass