zoukankan      html  css  js  c++  java
  • (三十四)线程的队列,协程

    一、线程的其他方法

    1.threading.current_thread()获取对象可以使用的方法
    def fn():
        pass
    t = Thread(target=fn,)
    t.start()
    obj = threading.current_thread()
    print(obj.getName(), obj.name)
    print(obj.ident)
    

      2.threading直接可以使用的方法 

    print(threading.enumerate())#获取当前活跃的线程的列表
    print(threading.active_count())#获取当前活跃的线程的总数
    

      

    二、线程队列

    1. 普通队列
    import queue
    q = queue.Queue(5)#不给数量,这个队列就是无限大的
    q.put(1)
    q.put(2)
    q.put(3)
    q.put(4)
    q.put(5)
    #print(q.full())#判断队列是否已满,不过有时不太准确
    #print(q.qsize())#获取队列中元素的的数量,其实这个方法里面里面也是使用的len()函数
    try:
        # q.put(6)#如果队列装满了,会一直停留在这里
        q.put_nowait(6)#如果队列满了,会报错,使用try后,可以抓取异常,然后继续向下执行
    except Exception:
        print('zhe queue is full')
    #print(q.empty())#查看队列是否已空,不过有时不太准确
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    try:
        print(q.get())
    except Exception:
        print('zhe queue is empty')
    

      

       2.LifoQueue--先进后出队列,获取顺序类似栈

    这就是一个继承了Queue的列表,其他的方法就是继承于Queue

     

    q = queue.LifoQueue(3)
    q.put(1)#添加数据就是向列表里append()数据
    q.put(2)
    q.put(3)
    
    print(q.get())#就是使用pop()删除列表
    print(q.get())
    print(q.get())
    结果:
    3
    2
    1
    

      

    第一步初始化一个列表:

    def _init(self, maxsize):
        self.queue = []
    

      

    第二步添加数据:

    def _put(self, item):
        self.queue.append(item)
    

      

    第三部删除数据:

    def _get(self):
        return self.queue.pop()
    

      

    3.PriorityQueue--优先级队列

    q = queue.PriorityQueue()
    q.put((3,'4'))
    q.put((2,3))
    q.put((1,'d'))
    q.put((5,'s'))
    q.put((4,'w'))
    
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    结果:
    (1, 'd')
    (2, 3)
    (3, '4')
    (4, 'w')
    (5, 's')
    

      

    结果按照元组中第一个元素的ASCII码的升序排序后输出,如果第一元素相等,就按照第二个元素的ASCII码的升序排列,以此类推。但是,字典元素不可比较。相对应比较的两个元素必须是同类型的。

    优先级队列也是一个列表:

    def _init(self, maxsize):
        self.queue = []
    

      

    就是增加和获取时,与列表有些区别。

    三、线程池

    1. ThreadPoolExecutor

    (1) map

    def f(n):
        time.sleep(0.5)
        print(n)
    t = ThreadPoolExecutor(4)  # 默认数量是,CPU个数的5倍
    t.map(f, range(10))
    

      

    (2)submit()

    def f(n):
        time.sleep(0.3)
        # print(n)
        return n**2
    Def fn(m):
    Print(m)
    t = ThreadPoolExecutor(4)  # 默认数量是,CPU个数的5倍
    t_lst = []
    for i in range(10):
        #功能后面的参数是无敌传参,*args,**kwargs,传递实参的个数不限制,但是形参的个数与形式也要跟实参的一一对应上
        res = t.submit(f, n=i)
    #t.submit()..add_done_callback(fn)#回调函数
    
        #print(res)#返回的是结果对象
        # print(res.result())#这也是一个不拿到结果,誓不罢休的方法
        t_lst.append(res)
    
    # for th in t_lst:#在shutdown()之前是每四个一次显示出来
    #     print(th.result())
    
    # 相当于进程池的close()和join()两个方法,其实里面是让每个线程都调用了join().
    t.shutdown()
    
    for th in t_lst:#会一下子展示出来数据
        print(th.result())
    

      

    2.ProcessPoolExecutor

       ThreadPoolExcutor的使用方法一样大的。

    四、协程

    协程是线程里最小的执行单元。首先得下载两个模块--greenletgevent

    1. greenlet
    from greenleet import greenlet
    
    def f1():
        print('f1---1111')
        g2.switch()
        print('f1---2222')
    def f2():
        print('f2---1111')
        g1.switch()
    
    g1 = greenlet(f1)
    g2 = greenlet(f2)
    g1.switch()
    
    结果:
    f1---1111
    f2---1111
    f1---2222
    
    def f1(c):
        print('f1---1111',c)
        g2.switch('Tom')
        print('f1---2222',c)
    def f2(c):
        print('f2---1111',c)
        g1.switch()#此处也可以添加参数,结果和现在就不一样了,可以试试看
    g1 = greenlet(f1)
    g2 = greenlet(f2)
    g1.switch('TOM')
    结果:
    f1---1111 TOM
    f2---1111 Tom
    f1---2222 TOM
    

      

    greenlet利用switch切换,执行不同代码块的功能。

    2.gevent

    def f1():
        print('f1---11111')
        gevent.sleep(1)
    #time.sleep(1)
        print('f1---22222')
    
    def f2():
        print('f2---11111')
        gevent.sleep(2)
    #time.sleep(1)
        print('f2---2222')
        
    g1 = gevent.spawn(f1)
    g2 = gevent.spawn(f2)
    
    g1.join()#需要有
    g2.join()
    #gevent.joinall([g1,g2])#相当于上面的两个一起
    

      

    gevent只识别自己的sleep()time.sleep()不能被识别。为了类似time.sleep()这样的阻塞被识别(还有input(),打开文件,文件或网络读取数据等),使用下面的方式:

    from gevent import monkey; monkey.patch_all()这句话放到文件的开头。

     例子:

    from gevent import monkey; monkey.patch_all()
    import gevent
    import requests
    def eat(name):
        print('%s eat 1' %name)
        # gevent.sleep(0.002)
        content = requests.get(url="https://www.baidu.com").text
        print("------->>>", content)
        print('%s eat 2' %name)
    
    def play(name):
        print('%s play 1' %name)
        # gevent.sleep(0.001)
        content = requests.get(url="https://www.sogou.com/")
        print(">>>>>>>>", content)
        print('%s play 2' %name)
    
    
    g1=gevent.spawn(eat,'lisi')
    g2=gevent.spawn(play,name='zhangsan')
    g1.join()
    g2.join()
    #或者gevent.joinall([g1,g2])
    print('主')
    

      

    例子:

    from gevent import spawn,joinall,monkey;monkey.patch_all()
    import time
    def task(pid):
        """
        Some non-deterministic task
        """
        time.sleep(0.5)
        print('Task %s done' % pid)
    
    def synchronous():
        for i in range(10):
            task(i)
    
    def asynchronous():
        g_l=[spawn(task,i) for i in range(10)]
        joinall(g_l)
    
    if __name__ == '__main__':
        s1 = time.time()
        print('Synchronous:')
        synchronous()
        print("11===", time.time() - s1) # 5.021262884140015
    
        s2 = time.time()
        print('Asynchronous:')
        asynchronous()
        print("22===", time.time() - s2) # 0.5015802383422852
    

      

      

      

    Python查看API:https://docs.python.org/3.7/library/os.html
    

      

  • 相关阅读:
    java 爬虫 爬取豆瓣 请不要害羞 图片
    Intellij idea 基本配置
    Linux 基本操作
    Java 快速排序
    Codeforces 986D Perfect Encoding FFT
    Codeforces 749E Gosha is hunting 二分+DP
    BZOJ5305 [Haoi2018]苹果树
    Codeforces 666E Forensic Examination SAM+权值线段树
    BZOJ3712[PA2014]Fiolki 建图+倍增lca
    Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP
  • 原文地址:https://www.cnblogs.com/asia-yang/p/10356214.html
Copyright © 2011-2022 走看看