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

原文地址:https://www.cnblogs.com/sunxiuwen/p/14000879.html