Python中的非阻塞,非并发任务

alf*_*eza 4 python events multithreading

我正在开发一个非常小的Python库,它必须是非阻塞的.

在某些生产代码上,在某些时候,将完成对此库的调用,并且它需要自己完成工作,以最简单的形式,它将是一个需要将某些信息传递给服务的可调用的.

这种"将信息传递给服务"是一项非密集型任务,可能会将一些数据发送到HTTP服务或类似的东西.它也不需要并发或共享信息,它确实需要在某个时刻终止,可能需要超时.

我之前使用过该threading模块,它似乎是最合适的使用方法,但是使用这个库的应用程序是如此之大,以至于我担心会遇到线程限制.

在本地测试中,我能够达到约2500个线程产生的限制.

有一个很好的可能性(考虑到应用程序的大小)我可以很容易地达到这个限制.考虑到以高速率放置任务的内存含义,它也让我厌倦了使用队列.

我也看过了,gevent但是我看不到能够产生一些可以做某些工作并且没有加入就终止的东西的例子.我经历过的例子,在那里调用.join()了一个Greenletgreenwlet或一系列greenlets.

我不需要知道正在完成的工作的结果!它只需要启动并尝试与HTTP服务进行通信,如果没有,则会以合理的超时死亡.

我误解了指南/教程gevent吗?是否还有其他可能以完全非阻塞的方式生成一个无法达到~2500限制的可调用对象?

这是线程中的一个简单示例,它可以像我期望的那样工作:

from threading import Thread


class Synchronizer(Thread):


    def __init__(self, number):
        self.number = number
        Thread.__init__(self)

    def run(self):
        # Simulating some work
        import time
        time.sleep(5)
        print self.number

for i in range(4000): # totally doesn't get past 2,500
    sync = Synchronizer(i)
    sync.setDaemon(True)
    sync.start()
    print "spawned a thread, number %s" % i
Run Code Online (Sandbox Code Playgroud)

这就是我用gevent尝试过的,它显然会在最后阻止看到工人做了什么:

def task(pid):
    """
    Some non-deterministic task
    """
    gevent.sleep(1)
    print('Task', pid, 'done')


for i in range(100):
    gevent.spawn(task, i)
Run Code Online (Sandbox Code Playgroud)

编辑: 我的问题源于我不熟悉gevent.虽然Thread代码确实产生了线程,但它也阻止了脚本在执行某些工作时终止.

gevent除非你添加一个,否则在上面的代码中并没有真正做到这一点.join().我只需要看到gevent代码与衍生的greenlets一起工作就可以使它成为一个长期运行的过程.这肯定解决了我的问题,因为需要生成greenlets的代码是在一个框架内完成的,这个框架本身就是一个长时间运行的进程.

Amb*_*ber 5

join如果您希望主线程的持续时间比任何工作者都长,那么没有任何东西需要您调用gevent.

join调用的唯一原因是确保主线程的持续时间至少与所有工作者一样长(以便程序不会提前终止).