情况一:单进程单线程

  基于全局变量实现。

情况二:单进程多线程

  基于threading.local对象。

  threading.local对象,用于为每个线程开辟一块空间来保存它独有的值。

  1. # -*- coding: utf-8 -*-
  2. # @Author : Felix Wang
  3. # @time : 2018/7/5 15:43
  4.  
  5. import threading
  6.  
  7. # 使用threading.local()时取到的是想要的值,数据操作是安全的
  8. local_values = threading.local()
  9.  
  10. # 没有使用threading.local()时,取到的不是自己想要的值
  11. # class Foo(object):
  12. # def __init__(self):
  13. # self.name=0
  14. # local_values=Foo()
  15.  
  16. def func(num):
  17. local_values.name = num
  18. import time
  19. time.sleep(1)
  20. print(local_values.name, threading.current_thread().name)
  21.  
  22. for i in range(20):
  23. th = threading.Thread(target=func, args=(i,), name='线程{}'.format(str(i)))
  24. th.start()

单进程多线程情况

情况三:单进程单线程(多个协程),threading.local对象做不到。通过自定义类似threading.local对象

  1. # -*- coding: utf-8 -*-
  2. # @Author : Felix Wang
  3. # @time : 2018/7/5 16:06
  4. import threading
  5.  
  6. try:
  7. from greenlet import getcurrent as get_ident # 支持协程
  8. except ImportError:
  9. try:
  10. from thread import get_ident
  11. except ImportError:
  12. from _thread import get_ident # 获取线程的唯一标识
  13.  
  14. # 实现方式一
  15. class Local(object):
  16. def __init__(self):
  17. self.storage = {}
  18. self.get_ident = get_ident
  19.  
  20. def set(self, k, v):
  21. ident = self.get_ident()
  22. origin = self.storage.get(ident)
  23. if not origin:
  24. origin = {k: v}
  25. else:
  26. origin[k] = v
  27. self.storage[ident] = origin
  28.  
  29. def get(self, k):
  30. ident = self.get_ident()
  31. origin = self.storage.get(ident)
  32. if not origin:
  33. return None
  34. return origin.get(k, None)
  35.  
  36. local_values = Local()
  37.  
  38. def task(num):
  39. local_values.set('name', num)
  40. import time
  41. time.sleep(1)
  42. print(local_values.get('name'), threading.current_thread().name)
  43.  
  44. for i in range(20):
  45. th = threading.Thread(target=task, args=(i,))
  46. th.start()
  47.  
  48. # 实现方式二
  49. class Local2(object):
  50. def __init__(self):
  51. object.__setattr__(self, '__storage__', {})
  52. object.__setattr__(self, '__ident_func__', get_ident)
  53. # self.storage = {}
  54. # self.get_ident = get_ident
  55.  
  56. def __getattr__(self, name):
  57. try:
  58. return self.__storage__[self.__ident_func__()][name]
  59. except KeyError:
  60. raise AttributeError(name)
  61.  
  62. def __setattr__(self, key, value):
  63. ident = self.__ident_func__()
  64. storage = self.__storage__
  65. try:
  66. storage[ident][key] = value
  67. except KeyError:
  68. storage[ident] = {key: value}
  69.  
  70. local_values2 = Local2()
  71.  
  72. def task(num):
  73. local_values2.name = num
  74. import time
  75. time.sleep(1)
  76. print(local_values2.name, threading.current_thread().name)
  77.  
  78. for i in range(20, 40):
  79. th = threading.Thread(target=task, args=(i,))
  80. th.start()

自定义local对象

flask框架(十二):上下文管理***的更多相关文章

  1. Flask框架(二)—— 反向解析、配置信息、路由系统、模板、请求响应、闪现、session

    Flask框架(二)—— 反向解析.配置信息.路由系统.模板.请求响应.闪现.session 目录 反向解析.配置信息.路由系统.模板.请求响应.闪现.session 一.反向解析 1.什么是反向解析 ...

  2. python flask框架学习(二)——第一个flask程序

    第一个flask程序 学习自:知了课堂Python Flask框架——全栈开发 1.用pycharm新建一个flask项目 2.运行程序 from flask import Flask # 创建一个F ...

  3. Flask 学习 十二 用户评论

    评论在数据库中的表示 由于评论和2个模型有关系,分别是谁发了评论,以及评论了哪个文章,所以这次要更新数据库模型 models.py 创建用户评论数据库模型 class Comment(db.Model ...

  4. Linux学习之CentOS(十二)------磁盘管理之 磁盘的分区、格式化、挂载(转)

    磁盘分区.格式化.挂载磁盘分区    新增分区    查询分区    删除分区磁盘格式化    mkfs    mke2fs磁盘挂载与卸载    mount    umount 磁盘的分区.格式化.挂 ...

  5. flask框架(二)——flask4剑客、flask配置文件的4种方式

    之前学习的Django有必备三板斧:render,HttpResponse,redirect,JsonResponse 在flask也有,但是有些不同 一.Flask4剑客 1.直接返回字符串(ret ...

  6. flask框架(二):简单的登录demo

    一:main.py # -*- coding: utf-8 -*- # @Author : Felix Wang # @time : 2018/7/3 22:58 from flask import ...

  7. Linux学习之CentOS(十二)----磁盘管理之 认识ext文件系统(转)

    认识ext文件系统 硬盘组成与分割 文件系统特性 Linux 的 EXT2 文件系统(inode) 与目录树的关系 EXT2/EXT3 文件的存取与日志式文件系统的功能 Linux 文件系统的运行 挂 ...

  8. Flask框架(二)

    request @app.route('/requests/', method=['GET', 'POST']) def req(): print(request.data) #请求方式 print( ...

  9. flask第二十二篇——模板【4】过滤器

    请关注微信公众号:自动化测试实战 先来教大家一个pycharm设置默认模板的方法.我们每次新建模板或者平时写代码打开以后可能都要重复写# coding: utf-8这些代码,其实我们可以设置好模板,让 ...

  10. flask学习(十二):for循环遍历

    一. 字典的遍历 语法和python一样,可以使用items().keys().values().iteritems().iterkeys().itervalues() {% for k, v in ...

随机推荐

  1. windows server 2008 R2 Enterprise 防火墙开启允许远程桌面登录

    解决方法: 开始------ > 运行 ----- > gpedit.msc 打开“本地组策略编辑器”,按如下设置:计算机配置----->管理模板----->网络-----&g ...

  2. lua与c的交互(函数专用)

    Lua与C的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  读写L ...

  3. C#实现鼠标滚筒缩放界面的效果

    elementCanvas继承UserControl 声明属性: #region 缩放属性添加 float ratio = 1.0f; public float Ratio { set { ratio ...

  4. C# struct结构知识总结

    结构是一种值类型,使用struct关键字定义. 结构可以包含字段.常量.事件.属性.方法.构造函数.索引器.运算符和嵌套类型.但若结构中同时需要上述所有成员,应考虑将结构改为类. 嵌套类型:在类或构造 ...

  5. MySQL 5.7.18 zip版本的安装使用方法

    转自:https://www.cnblogs.com/nepulgh/p/7152618.html MySQL 5.7.18 zip版本的安装使用方法 这个版本的MySQL不像那种点击就可以立即安装, ...

  6. 什么是NoSQL,为什么要使用NoSQL?

    详见: https://blog.csdn.net/a909301740/article/details/80149552 https://baike.so.com/doc/5569749-57849 ...

  7. 附件上传vue组件封装(一)

    //父页面部分 <attachment @newFileList="newFileList" :operationType="operationType" ...

  8. 关于SAMBA的关键参考资源

    https://www.samba.org/samba/docs/man/ https://devel.samba.org/ http://www.ubiqx.org/cifs/ https://ww ...

  9. 《python解释器源码剖析》第10章--python虚拟机中的一般表达式

    10.0 序 上一章中,我们通过PyEval_EvalFrameEx看到了python虚拟机的整体框架,那么这一章我们将深入到PyEval_EvalFrameEx的各个细节当中,深入剖析python的 ...

  10. ORACLE 常用函数学习笔记

    1.字符串截取方法 --5SELECT INSTR('8.30~9.00', '~') FROM dual; --8.30SELECT SUBSTR ('8.30~9.00', 0, INSTR (' ...