2012-02-13 37 views
13

Tôi muốn ghi vào một tệp bằng phương pháp không chặn trong Python. Trên một số googling, tôi thấy rằng ngôn ngữ hỗ trợ fcntl để làm như vậy, nhưng phương pháp để thực hiện giống nhau không phải là rất rõ ràng với tôi.Làm thế nào để ghi vào một tập tin bằng cách sử dụng không chặn IO?

Đây là đoạn mã (Tôi không biết nơi tôi sẽ sai):

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") 

Đây có phải là cách chính xác để thực hiện một hoạt động IO non-blocking trên một tập tin? Tôi nghi ngờ điều đó. Ngoài ra, bạn có thể đề xuất bất kỳ mô-đun nào khác trong Python cho phép tôi làm như vậy không?

+0

thể trùng lặp của (http://stackoverflow.com/questions/319132/asynchronous-file-writing-possible-in-python) – jcollado

+0

[Asynchronous tập tin văn bản có thể trong python?] Không có nó, tôi cần phải giữ nó đơn giản bằng cách chỉ sử dụng fcntl :) – Rahul

Trả lời

14

Đây là cách bạn bật chế độ non-blocking trên cho một tập tin trong UNIX:

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

Trên UNIX, tuy nhiên, turning on non-blocking mode has no visible effect for regular files! Mặc dù tệp đang ở chế độ không chặn, cuộc gọi os.write sẽ không trở lại ngay lập tức, nó sẽ ngủ cho đến khi quá trình ghi hoàn tất. Để chứng minh điều đó cho chính mình thực nghiệm, hãy thử này:

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())) 

Bạn sẽ nhận thấy rằng cuộc gọi os.write không mất vài giây. Mặc dù cuộc gọi không bị chặn (về mặt kỹ thuật, nó không chặn, nó đang ngủ), cuộc gọi là không phải không đồng bộ.


AFAIK, không có cách nào để ghi vào tệp không đồng bộ trên Linux hoặc trên Windows. Bạn có thể mô phỏng nó, tuy nhiên, bằng cách sử dụng chủ đề. Twisted có một phương thức có tên là deferToThread cho mục đích này. Đây là cách bạn sử dụng nó:

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

Làm cách nào để truy cập vào đối tượng lò phản ứng từ bên trong một LineReciver hoặc giao thức khác được xây dựng bởi một nhà máy sản xuất máy chủ? – Sean

+0

Một ghi không chặn có thể được thực hiện cho một tập tin thông thường với POSIX AIO hoặc Windows IOCP. – strcat

4

Ghi được lưu trữ bởi hệ điều hành và được chuyển vào đĩa sau vài giây. Đó là, họ đang "không chặn" rồi. Bạn không phải làm bất cứ điều gì đặc biệt.

+0

Điều gì xảy ra nếu tập tin thực sự được gắn trên một mạng chia sẻ? Chắc chắn, cuộc gọi sẽ chỉ trở lại sau khi nhận được những lời cảm ơn? – Flimm

+1

Phụ thuộc vào hệ thống tệp từ xa và ngữ nghĩa được triển khai, đồng bộ hoặc không đồng bộ. Có những ví dụ về cả hai hoặc thậm chí là những thứ như "đồng bộ hóa khi đóng". – jcea

Các vấn đề liên quan