2012-02-13 1 views
13

파이썬에서 non-blocking 방법을 사용하여 파일에 쓰고 싶습니다. 일부 인터넷 검색에서 나는 언어가 fcntl을 지원한다는 것을 알았지 만이를 구현하는 방법은 나에게 분명하지 않습니다. 비 차단 IO를 사용하여 파일에 쓰는 방법은 무엇입니까?

코드 스 니펫 (나도 몰라 어디 내가 잘못 가고)있다 :

import os, fcntl 
nf = fcntl.fcntl(0,fcntl.F_UNCLK) 
fcntl.fcntl(0,fcntl.F_SETFL , nf | os.O_NONBLOCK) 
nf = open ("test.txt", 'a') 
nf.write (" sample text \n") 

이 파일에 비 차단 IO 작업을 수행 할 수있는 올바른 방법이 있나요? 나는 그것을 의심한다. 또한 파이썬에서 다른 모듈을 제안 할 수 있습니까?

+0

의 중복 가능성 (http://stackoverflow.com/questions/319132/asynchronous-file-writing-possible-in-python) – jcollado

+0

[파이썬에서 가능 쓰기 비동기 파일?] 아니오, 그냥 fcntl을 사용하여 간단하게 유지해야합니다 :) – Rahul

답변

14

이 당신이 설정하는 방법입니다 비 차단 UNIX에있는 파일에 모드 :

UNIX에
fd = os.open("filename", os.O_CREAT | os.O_WRONLY | os.O_NONBLOCK) 
os.write(fd, "data") 
os.close(fd) 

그러나 turning on non-blocking mode has no visible effect for regular files! 파일이 비 차단 모드에 있더라도 os.write 호출은 즉시 반환되지 않고 쓰기가 완료 될 때까지 대기 상태가됩니다. 실험적으로 자신에게 그것을 증명하려면 다음을 수행하십시오

import os 
import datetime 

data = "\n".join("testing\n" * 10 for x in xrange(10000000)) 
print("Size of data is %d bytes" % len(data)) 

print("open at %s" % str(datetime.datetime.now())) 
fd = os.open("filename", os.O_CREAT | os.O_WRONLY | os.O_NONBLOCK) 
print("write at %s" % str(datetime.datetime.now())) 
os.write(fd, data) 
print("close at %s" % str(datetime.datetime.now())) 
os.close(fd) 
print("end at %s" % str(datetime.datetime.now())) 

당신은 os.write 전화가 몇 초 정도 걸릴 않는 것을 알 수 있습니다. 호출이 비 블로킹 (기술적으로 블로킹이 아닌, 대기 중임) 되어도 호출은 이 아니고 비동기입니다.


AFAIK는 Linux 또는 Windows에서 비동기 적으로 파일에 쓸 수있는 방법이 없습니다. 그러나 스레드를 사용하여 시뮬레이션 할 수 있습니다. Twisted는이 목적으로 deferToThread이라는 메서드를 가지고 있습니다. 여기 당신이 그것을 사용하는 방법은 다음과 같습니다

from twisted.internet import threads, reactor 

data = "\n".join("testing\n" * 10 for x in xrange(10000000)) 
print("Size of data is %d bytes" % len(data)) 

def blocking_write(): 
    print("Starting blocking_write") 
    f = open("testing", "w") 
    f.write(data) 
    f.close() 
    print("End of blocking_write") 

def test_callback(): 
    print("Running test_callback, just for kicks") 

d = threads.deferToThread(blocking_code) 
reactor.callWhenRunning(cc) 
reactor.run() 
+0

LineReciver 또는 서버 팩토리에 의해 구축 된 다른 프로토콜 내에서 원자로 객체에 액세스하려면 어떻게해야합니까? – Sean

+0

POSIX AIO 또는 Windows IOCP를 사용하여 일반 파일에 비 차단 쓰기를 수행 할 수 있습니다. – strcat

4

쓰기는 OS에 의해 캐시되고 몇 초 후에 디스크에 덤프됩니다. 즉, 그들은 이미 "차단하지 못하고있다". 특별한 일을 할 필요가 없습니다.

+0

파일이 실제로 네트워크 공유에 마운트되면 어떻게됩니까? 확실하게, 응답은 승인을받은 후에 만 ​​되돌아 올 것입니까? – Flimm

+1

구현 된 원격 파일 시스템 및 의미에 따라 다릅니다. 동기식 또는 비동기식입니다. 두 가지 모두의 예나 심지어 "가까운 곳에 동기화"와 같은 것들이 있습니다. – jcea

관련 문제