gevent模块的使用中,如果“主线程”有非I/O的阻塞,会影响其他协程的执行?

发布于 2022-09-05 10:59:36 字数 1641 浏览 28 评论 0

gevent模块的使用中,如果“主线程”(这个表述不太准确)中,有非IO的阻塞操作(比如 input),就会让其他协程无法执行?

比如:

例子①

from gevent import monkey; monkey.patch_all()
import gevent,urllib.request,time

def f(url):
    print('GET: %s' % url)
    resp = urllib.request.urlopen(url)
    data = resp.read()
    print('%d bytes received from %s.' % (len(data), url))

gevent.spawn(f, 'http://www.163.org/')
gevent.spawn(f, 'http://www.qq.com/')
gevent.spawn(f, 'http://www.baidu.com/')

while 1:
    msg = input('>> ').strip()
    print(msg)

或者 将 while 1: 中的代码换成 pass,协程都貌似不会执行的样子。

但是如果 将 while 1: 中的代码 换成 time.sleep(1) 这种,就可以执行了

这是,为什么???

如果我一定需要 “主线程” 中有 input 这种阻塞,该如何处理?

比如如下代码,用来获取url的主页长度。要求:
①在一个死循环中,input 接收输入

②如果输入 get + 域名,开启一个协程在后台处理获取url长度的操作,该操作不能阻塞 “主线程”,即:输入后,就可以立刻进行下一次输入,不等待

③如果输入 result + 域名,就返回 域名 对应url的主页长度(还没处理完就提示等待)

#! /usr/bin/env python
#  -*- coding:utf-8 -*-

# 错误示例  

import urllib.request,gevent

res = {}

def get_url(url):
    resp = urllib.request.urlopen(url)
    res[dn] = len(resp.read())


while 1:
    cmd = input('>> ').strip()

    if cmd.startswith('get'):
        dn = cmd.split()[1]
        url = 'http://%s.com'%dn
        gevent.spawn(get_url,url)
        print('Start handling the request,plz wait a moment...')

    elif cmd.startswith('result'):
        dn = cmd.split()[1]
        if dn in res:
            print(res[dn])
            del res[dn]
        else:
            print('Request is handling...')
    else:
        print('Commad not found')

以上代码需如何修改,才能达到要求,我知道用多线程/多进程一定是可以的,如果就用gevent该如何实现呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧时光的容颜 2022-09-12 10:59:36

记得哪篇文档里提到了 gevent就不要有这种阻塞操作 本身不符合协程的意义

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文