Python gevent Я не вижу, чтобы обезьяна исправила файл по умолчанию, открывающий/читающий/записывающий/закрывающий, как сделать файл io в gevent асинхронным

В патче gevent monkey я ничего не видел о работе файлового объекта по умолчанию. Как я могу использовать асинхронное чтение/запись файлов в программах на основе gevent?


person truease.com    schedule 16.07.2012    source источник


Ответы (3)


Вы можете использовать класс gevent fileobject.FileObjectThreadPool, доступный в 1.0b3:

pip install http://gevent.googlecode.com/files/gevent-1.0b3.tar.gz#egg=gevent

Тогда ваш пример станет:

#!/usr/bin/env python
import gevent
from gevent.fileobject import FileObjectThreadPool
import datetime


def hi():
    while True:
        print datetime.datetime.now(), "Hello"
        gevent.sleep( 1 )

def w():
    print "writing..."
    s = "*"*(1024*1024*1024)
    print 'about to open'
    f_raw = open( "./a.txt", "wb" )
    f = FileObjectThreadPool(f_raw, 'wb')
    f.write(s)
    f.close()
    print 'write done'

t1 = gevent.spawn(hi)
t2 = gevent.spawn(w)
ts = [t1,t2]
gevent.joinall( ts )

Я вижу следующий вывод с этим кодом:

writing...
about to open
2012-08-13 13:00:27.876202 Hello
2012-08-13 13:00:28.881119 Hello
2012-08-13 13:00:29.959642 Hello
...
2012-08-13 13:00:58.010001 Hello
2012-08-13 13:00:59.010146 Hello    
2012-08-13 13:01:00.010248 Hello
write done
2012-08-13 13:01:01.469547 Hello
...
person mrkhingston    schedule 13.08.2012
comment
Извинения - в зависимости от того, какую ОС вы используете, это может не сработать для вас. Я только что сообщил об ошибке, что это не работает в Ubuntu 12.04: code.google .com/p/gevent/issues/detail?id=150. Ребята из gevent довольно хорошо исправляют ошибки, так что скоро это может работать на всех платформах. - person mrkhingston; 15.08.2012
comment
К вашему сведению, Денис исправил ошибку 150 в HEAD gevent, которая скоро будет выпущена как gevent-1.0b4. Однако мои первоначальные инструкции по использованию FileObject были неверными — я отредактировал свой ответ, чтобы использовать FileObjectThreadPool. - person mrkhingston; 31.08.2012
comment
Учтите, что Денис недавно изменил имя FileObjectThreadPool на FileObjectThread - person Nikola Kotur; 03.04.2013

Только что сделал тест, говорит, что запись большого файла заблокирует цикл событий

#!/usr/bin/env python
import gevent
import datetime


def hi():
    while True:
        print datetime.datetime.now(), "Hello"
        gevent.sleep( 1 )

def w():
    print "writing..."
    s = "*"*(1024*1024*1024)
    f = open( "e:/a.txt", "wb" )
    f.write(s)
    f.close()

t1 = gevent.spawn(hi)
t2 = gevent.spawn(w)
ts = [t1,t2]
gevent.joinall( ts )

результат таков:

e:\zPython\zTest>gevent.write.large.file.py
writing...  # wait a long time here
write done.
2012-07-16 09:53:23.784000 Hello
2012-07-16 09:53:24.786000 Hello
2012-07-16 09:53:25.788000 Hello
person truease.com    schedule 16.07.2012
comment
Разве это не часть вопроса — часть «что вы пробовали» — вместо ответа? - person Chris Wesseling; 23.05.2014

Вы можете использовать пул потоков (начиная с gevent 1.0):

>>> import gevent.threadpool
>>> pool = gevent.threadpool.ThreadPool(5)
>>> pool.apply(w)
person Denis Bilenko    schedule 16.07.2012
comment
да, я могу использовать пул потоков. Но мой вопрос не в том, чтобы сосредоточиться на использовании gevent. Я хочу найти способ сделать асинхронный файловый ввод-вывод как в Windows, так и в Linux. Конечно, с языком python и работать вместе с gevent. - person truease.com; 16.07.2012