python多线程库vthread的使用

 线程池的多线程装饰
 对代码入侵较小,例如

 >>> import vthread
 >>> import time
 >>>
 >>> # 只需要加下面这一行就可以将普通迭代执行函数变成线程池多线程执行
 >>> @vthread.pool(5) # 对于 foolfunc 开启5个线程池
 >>> def foolfunc(num):
 ...     time.sleep(1)
 ...     print(f"foolstring, foolnumb:{num}")
 >>>
 >>> # 默认参数:pool_num=None,join=False,log=True,gqueue=0
 >>> # pool_num不选时就自动选 cpu 核心数
 >>> # 就是说,装饰方法还可以更简化为 @vthread.pool()
 >>> # join参数不建议在主线程内打开。
 >>>
 >>> for i in range(10):
 ...     foolfunc(i)
 [  Thread-3  ] foolstring, foolnumb:1
 [  Thread-2  ] foolstring, foolnumb:2
 [  Thread-1  ] foolstring, foolnumb:0
 [  Thread-5  ] foolstring, foolnumb:3
 [  Thread-4  ] foolstring, foolnumb:4
 [  Thread-3  ] foolstring, foolnumb:5
 [  Thread-2  ] foolstring, foolnumb:6
 [  Thread-1  ] foolstring, foolnumb:7
 [  Thread-5  ] foolstring, foolnumb:8
 [  Thread-4  ] foolstring, foolnumb:9
 >>> # 这里的函数执行都是放在伺服线程中执行。
 >>> # 如果不指定 gqueue 参数,默认是共用0号队列
 >>> # 不指定 gqueue 参数给多个函数装饰的情况下
 >>> # 用的都是一组伺服线程
 >>>
==============================================================
 可以尝试用gqueue的参数来实现不同函数不同作用域
 开启多组伺服线程

 >>>
 >>> import vthread
 >>> pool1 = vthread.pool(5,gqueue=1) # 开5个伺服线程,组名为1
 >>> pool2 = vthread.pool(1,gqueue=2) # 开1个伺服线程,组名为2
 >>>
 >>> @pool1
 >>> def foolfunc1(num):
 >>>     time.sleep(1)
 >>>     print(f"foolstring1, foolnumb1:{num}")
 >>> @pool2
 >>> def foolfunc2(num):
 >>>     time.sleep(1)
 >>>     print(f"foolstring2, foolnumb2:{num}")
 >>>
 >>> for i in range(5): foolfunc1(i)
 >>> for i in range(5): foolfunc2(i)
 [  Thread-1  ] foolstring1, foolnumb1:0
 [  Thread-3  ] foolstring1, foolnumb1:2
 [  Thread-4  ] foolstring1, foolnumb1:3
 [  Thread-2  ] foolstring1, foolnumb1:1
 [  Thread-6  ] foolstring2, foolnumb2:0
 [  Thread-5  ] foolstring1, foolnumb1:4
 [  Thread-6  ] foolstring2, foolnumb2:1
 [  Thread-6  ] foolstring2, foolnumb2:2
 [  Thread-6  ] foolstring2, foolnumb2:3
 [  Thread-6  ] foolstring2, foolnumb2:4
 >>>
 >>> # 通过上面的代码执行就很容易发现
 >>> # pool2 装饰后的函数频率、线程数和 pool1 的不一样
 >>> # 你可能某几个函数要用一个组,某几个函数用另一组
 >>> # 分组功能可以更加灵活地使用线程池
 >>>
==============================================================
     |
     |这里是方法定义:
     |
     |  __call__(self, func)
     |      #==============================================================
     |      # 类装饰器入口
     |      #==============================================================
     |
     |  __init__(self, pool_num=None, gqueue=0, join=False, log=True, monitor=True)
     |      #==============================================================
     |      # **kw
     |      #     :pool_num  伺服线程数量
     |      #     :gqueue    全局队列表的index,默认0,建议用数字标识
     |      #     :join      多线程是否join
     |      #     :log       print函数的输出时是否加入线程名作前缀
     |      #==============================================================
     |
     |  ----------------------------------------------------------------------
     | 类方法定义:
     |
     |  change_thread_num(num, gqueue=0) from builtins.type
     |      #==============================================================
     |      # 通过组名字,用来修改线程数量的函数,默认修改gqueue=0的组
     |      # 是静态函数,你可以直接用 vthread.self.change_thread_num(3)修改
     |      # 就是简单的多退少补,用来动态修改伺服线程数量的。
     |      #
     |      # 因为原理是向线程队列注入停止标记,线程执行和线程接收停止信号是互斥安全的
     |      # 也是在设计初对任务执行完整性的一种考虑
     |      #==============================================================
     |
     |  close_all() from builtins.type
     |      #==============================================================
     |      # 关闭所有伺服线程
     |      #==============================================================
     |
     |  close_by_gqueue(gqueue=0) from builtins.type
     |      #==============================================================
     |      # 通过组名关闭该组所有的伺服线程
     |      # 默认关闭gqueue=0组的所有伺服线程
     |      #==============================================================
     |
     |  main_monitor() from builtins.type
     |      #==============================================================
     |      # 对主线程进行监视的函数
     |      # 一旦主线程执行完毕就会向所有线程池函数队列尾注入停止标记
     |      # 使所有的线程在执行完任务后都停止下来
     |      # 对于命令行使用的 python 脚本尤为重要
     |      # 因为如果所有线程不停止的话,控制权就不会交还给命令窗口
     |      #
     |      # 在任意被含有该函数的装饰类装饰的情况下,这个是默认被打开的
     |      # 可以在装饰时通过设置 monitor 参数是否打开,默认以第一个装饰器设置-为
     |      #==============================================================
     |
     |  show() from builtins.type
     |      #==============================================================
     |      # 简单的打印一下当前的线程池的组数
     |      # 以及打印每一组线程池的线程数量
     |      #
     |      # >>> vthread.show()
     |      # [ MainThread ] threads group number: 3
     |      # [ MainThread ] gqueue:0, alive threads number:6
     |      # [ MainThread ] gqueue:1, alive threads number:5
     |      # [ MainThread ] gqueue:2, alive threads number:2
     |      # >>>
     |      #==============================================================
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  join = False

     class thread(builtins.object)
     |  thread(num=1, join=False, log=True)
     |
==============================================================
 普通的多线程装饰

 >>> import vthread
 >>>
 >>> # 将 foolfunc 变成动态开启3个线程执行的函数
 >>> @vthread.thread(3) # 默认参数:join=False,log=True
 ... def foolfunc():
 ...     print("foolstring")
 >>>
 >>> foolfunc() # 一次执行开启三个线程执行相同函数
 [  Thread-1  ]: foolstring
 [  Thread-2  ]: foolstring
 [  Thread-3  ]: foolstring
 >>>
==============================================================
 为了和pool的使用方法共通(一次函数执行只是一次函数单独执行的效果)
 这里添加了一种更为简便的装饰手段

 >>> import vthread
 >>>
 >>> # 将 foolfunc 变成开启新线程执行的函数
 >>> @vthread.vthread # 这时的 vthread.thread 等同于 vthread.thread(1)
 ... def foolfunc():
 ...     print("foolstring")
 >>>
 >>> for i in range(4):
 ...     foolfunc() # 每次执行都会开启新线程,默认不join。
 [  Thread-1  ]: foolstring
 [  Thread-2  ]: foolstring
 [  Thread-3  ]: foolstring
 [  Thread-4  ]: foolstring
 >>>

 不过需要注意的是,不要将 vthread.thread 带参数和不带参数的装饰器混用
 可能会导致一些不可预知的异常。
==============================================================
     |
     |  Methods defined here:
     |
     |  __call__(self, func)
     |      #==============================================================
     |      # 类装饰器入口
     |      #==============================================================
     |
     |  __init__(self, num=1, join=False, log=True)
     |      #==============================================================
     |      # *args
     |      #     :num   线程数量
     |      # **kw
     |      #     :join  多线程是否join
     |      #     :log   print函数的输出时是否加入线程名作前缀
     |      #==============================================================
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)

FUNCTIONS
    atom(func)
        #==============================================================
        # 对任意函数进行原子包装(加锁)
        #==============================================================

    patch_print()
        #==============================================================
        # print 补丁函数
        #
        # monkey patch 式的修改
        # 对python内建 print 函数进行加锁
        # 使其在调试阶段能更方便使用
        #==============================================================

    toggle(toggle=False, name='thread')
        #==============================================================
        # 开关显示方式
        # 目前提供修改的参数有三个:
        # 1. "thread"  # 是否在print时在最左显示线程名字
        # 2. "error"   # 是否显示error信息
        #==============================================================

    unpatch_all(can_be_repatch=False)
        #==============================================================
        # 去补丁函数
        # :can_be_repatch=False
        #   因为设计是在每次装饰时就会默认patch一次
        #   卸载后不可被重新patch的参数添加就是为了
        #   可以使得在头部执行这个函数后后面的装饰都不会再patch
        #==============================================================

DATA
    __all__ = ['thread', 'pool', 'atom', 'patch_print', 'toggle', 'unpatch...
    __author_email__ = 'opaquism@hotmail.com'
    __description__ = 'the best threadpool pack.'
    __title__ = 'vthread'
    lock = <unlocked _thread.RLock object owner=0 count=0>
    orig_func = {}
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值