快乐学习
前程无忧、中华英才非你莫属!

Python-异步编程-gevent-6

队列

队列是有序的数据集,它们具有通常的put/get 操作,但以一种可以在 Greenlets 之间安全操作的方式编写。

例如,如果一个 Greenlet 从队列中抓取一个项目,另一个同时执行的 Greenlet 将不会抓取同一个项目。

import gevent
from gevent.queue import Queue

tasks = Queue()

def worker(n):
    while not tasks.empty():
        task = tasks.get()
        print('Worker %s got task %s' % (n, task))
        gevent.sleep(0)

    print('Quitting time!')

def boss():
    for i in range(1, 25):
        tasks.put_nowait(i)

gevent.spawn(boss).join()

gevent.joinall([
    gevent.spawn(worker, 'steve'),
    gevent.spawn(worker, 'john'),
    gevent.spawn(worker, 'nancy'),
])

'''
输出结果

Worker steve got task 1
Worker john got task 2
Worker nancy got task 3
Worker steve got task 4
Worker john got task 5
Worker nancy got task 6
Worker steve got task 7
Worker john got task 8
Worker nancy got task 9
Worker steve got task 10
Worker john got task 11
Worker nancy got task 12
Worker steve got task 13
Worker john got task 14
Worker nancy got task 15
Worker steve got task 16
Worker john got task 17
Worker nancy got task 18
Worker steve got task 19
Worker john got task 20
Worker nancy got task 21
Worker steve got task 22
Worker john got task 23
Worker nancy got task 24
Quitting time!
Quitting time!
Quitting time!

Process finished with exit code 0

'''

从输出结果中,可以看出从队列取出来的资源,并没有重复。

队列也可以阻塞put或get在需要时阻塞。

每个put and get操作都有一个非阻塞对应物,put_nowait并且 get_nowait不会阻塞,而是在操作不可能时引发gevent.queue.Empty或 引发gevent.queue.Full。

在这个例子中,我们让老板同时运行到工人,并且对队列有一个限制,防止它包含三个以上的元素。此限制意味着put 操作将阻塞,直到队列上有空间。相反,get如果队列上没有要获取的元素,则操作将阻塞,它还需要一个超时参数,以允许队列退出,gevent.queue.Empty如果在超时的时间范围内找不到工作,则异常退出 。

import gevent
from gevent.queue import Queue, Empty

tasks = Queue(maxsize=3)  # 队列最大3

def worker(name):
    try:
        while True:
            task = tasks.get(timeout=1)  # 将队列大小减 1
            print('Worker %s got task %s' % (name, task))
            gevent.sleep(0)
    except Empty:
        print('Quitting time!')

def boss():
    """
    老板会等到个别工人下班
     free,因为任务队列的最大大小是 3。
    """

    for i in range(1, 10):
        tasks.put(i)  # 只能添加3次,被阻塞了
        print('我是迭代1')
    print('在迭代 1 中分配所有工作')

    for i in range(10, 20):
        tasks.put(i)
        print('我是迭代2')
    print('在迭代 2 中分配所有工作')

gevent.joinall([
    gevent.spawn(boss),
    gevent.spawn(worker, 'steve'),
    gevent.spawn(worker, 'john'),
    gevent.spawn(worker, 'bob'),
])

'''
我是迭代1
我是迭代1
我是迭代1
Worker steve got task 1
Worker john got task 2
Worker bob got task 3
我是迭代1
我是迭代1
我是迭代1
Worker steve got task 4
Worker john got task 5
Worker bob got task 6
我是迭代1
我是迭代1
我是迭代1
在迭代 1 中分配所有工作
Worker steve got task 7
Worker john got task 8
Worker bob got task 9
我是迭代2
我是迭代2
我是迭代2
Worker steve got task 10
Worker john got task 11
Worker bob got task 12
我是迭代2
我是迭代2
我是迭代2
Worker steve got task 13
Worker john got task 14
Worker bob got task 15
我是迭代2
我是迭代2
我是迭代2
Worker steve got task 16
Worker john got task 17
Worker bob got task 18
我是迭代2
在迭代 2 中分配所有工作
Worker steve got task 19
Quitting time!
Quitting time!
Quitting time!

Process finished with exit code 0

'''
打赏

未经允许不得转载:同乐学堂 » Python-异步编程-gevent-6

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

特别的技术,给特别的你!

联系QQ:1071235258QQ群:367203382
error: Sorry,暂时内容不可复制!