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
人生苦短,我用python!