Chính xác thì file.flush () của Python đang làm gì?


137

Tôi đã tìm thấy điều này trong tài liệu Python cho Đối tượng tệp :

flush () không nhất thiết phải ghi dữ liệu của tệp vào đĩa. Sử dụng flush () theo sau bởi os.fsync () để đảm bảo hành vi này.

Vì vậy, câu hỏi của tôi là: chính xác thì Python flushđang làm gì? Tôi nghĩ rằng nó buộc phải ghi dữ liệu vào đĩa, nhưng bây giờ tôi thấy rằng nó không. Tại sao?

Câu trả lời:


219

Thông thường có hai cấp độ đệm liên quan:

  1. Bộ đệm nội bộ
  2. Bộ đệm hệ điều hành

Bộ đệm nội bộ là bộ đệm được tạo bởi bộ thực thi / thư viện / ngôn ngữ mà bạn đang lập trình và có nghĩa là tăng tốc mọi thứ bằng cách tránh các cuộc gọi hệ thống cho mỗi lần ghi. Thay vào đó, khi bạn ghi vào một đối tượng tệp, bạn ghi vào bộ đệm của nó và bất cứ khi nào bộ đệm đầy, dữ liệu được ghi vào tệp thực tế bằng các lệnh gọi hệ thống.

Tuy nhiên, do bộ đệm của hệ điều hành, điều này có thể không có nghĩa là dữ liệu được ghi vào đĩa . Nó có thể chỉ có nghĩa là dữ liệu được sao chép từ bộ đệm được duy trì bởi thời gian chạy của bạn vào bộ đệm được duy trì bởi hệ điều hành.

Nếu bạn viết một cái gì đó, và nó kết thúc trong bộ đệm (chỉ) và nguồn điện bị cắt vào máy của bạn, dữ liệu đó không nằm trên đĩa khi máy tắt.

Vì vậy, để giúp với điều đó, bạn có flushfsync phương thức phương thức tương ứng.

Đầu tiên, flushđơn giản sẽ ghi ra bất kỳ dữ liệu nào lưu lại trong bộ đệm chương trình vào tệp thực tế. Thông thường, điều này có nghĩa là dữ liệu sẽ được sao chép từ bộ đệm chương trình sang bộ đệm hệ điều hành.

Cụ thể điều này có nghĩa là nếu một quá trình khác có cùng tệp được mở để đọc, nó sẽ có thể truy cập dữ liệu bạn vừa xóa vào tệp. Tuy nhiên, điều đó không nhất thiết có nghĩa là nó đã được lưu trữ "vĩnh viễn" trên đĩa.

Để làm điều đó, bạn cần gọi os.fsync phương thức đảm bảo tất cả các bộ đệm của hệ điều hành được đồng bộ hóa với các thiết bị lưu trữ mà nói cách khác, phương thức đó sẽ sao chép dữ liệu từ bộ đệm của hệ điều hành vào đĩa.

Thông thường, bạn không cần phải bận tâm với một trong hai phương pháp, nhưng nếu bạn đang ở trong một tình huống mà sự hoang tưởng về những gì thực sự kết thúc trên đĩa là một điều tốt, bạn nên thực hiện cả hai cuộc gọi theo hướng dẫn.


Phụ lục năm 2018.

Lưu ý rằng các đĩa có cơ chế bộ đệm hiện phổ biến hơn nhiều so với năm 2013, vì vậy bây giờ thậm chí còn có nhiều cấp độ bộ đệm và bộ đệm hơn. Tôi cho rằng các bộ đệm này cũng sẽ được xử lý bằng các cuộc gọi đồng bộ / xóa, nhưng tôi thực sự không biết.


10
Khi tôi sử dụng with file('blah') as fd: #dostuffcấu trúc, tôi biết nó đảm bảo đóng bộ mô tả tệp. Nó cũng tuôn ra hoặc đồng bộ hóa?
Marcin

3
@Marcin: Nó tuôn ra, nhưng KHÔNG đồng bộ.
Alex I

8
fsynclà cần thiết cho nguyên tử. bạn không thể mong đợi để đóng một tệp, mở lại nó và tìm nội dung của bạn mà không có fsyncở giữa. Nó thường hoạt động, nhưng nó không có trên linux với ext4 và các tùy chọn gắn kết mặc định. Cũng fsynckhông được đảm bảo để thực sự lật nam châm trên các đĩa, bởi vì 1: fsync có thể bị vô hiệu hóa (bằng chế độ máy tính xách tay) và 2: bộ đệm bên trong đĩa cứng có thể không được hướng dẫn để xả.
v.oddou

1
Có cách nào để xóa bộ đệm của hệ điều hành cho tất cả các tệp, nếu tệp được ghi bởi một quy trình khác không?
thuyền

1
fsync tương đối đắt tiền. Nói chung, bạn không viết phần mềm quan trọng cần tuân thủ 100% ACID và độ bền khi truy cập đĩa, và nếu bạn có thể nhận thức sâu sắc về nó và nên biết các bước bạn có thể thực hiện để có được những đảm bảo này . Gọi fsync sẽ đợi truy cập đĩa vật lý xảy ra để ghi dữ liệu vào đĩa, trong khi đó, việc xóa và đóng sẽ chỉ chờ dữ liệu được chuyển sang bộ nhớ đệm. Sự khác biệt tốc độ có lẽ là một số đơn đặt hàng cường độ.
Lasse V. Karlsen

10

Bởi vì hệ điều hành có thể không làm như vậy. Thao tác tuôn ra buộc dữ liệu tệp vào bộ đệm của tệp trong RAM và từ đó, công việc của HĐH thực sự gửi nó vào đĩa.


6
Bạn đúng, nhưng actuallytương đối ở đây: nếu thiết bị đích đã kích hoạt ghi bộ đệm, dữ liệu có thể không đạt tới các đĩa / chip thực tế khi os.fsync()trả về.
Frédéric Hamidi

7

Nó xóa bộ đệm bên trong, được cho là khiến HĐH ghi bộ đệm vào tệp. [1] Python sử dụng bộ đệm mặc định của HĐH trừ khi bạn cấu hình nó làm khác.

Nhưng đôi khi HĐH vẫn chọn không hợp tác. Đặc biệt với những điều tuyệt vời như trì hoãn ghi trong Windows / NTFS. Về cơ bản bộ đệm bên trong bị xóa, nhưng bộ đệm hệ điều hành vẫn đang giữ nó. Vì vậy, bạn phải yêu cầu HĐH ghi nó vào đĩa os.fsync()trong những trường hợp đó.

[1] http://docs.python.org/l Library / stdtypes.html


0

Về cơ bản, flush () dọn sạch bộ đệm RAM của bạn, sức mạnh thực sự của nó là cho phép bạn tiếp tục ghi vào nó sau đó - nhưng nó không nên được coi là tính năng ghi vào tệp tốt nhất / an toàn nhất. Đó là xả RAM của bạn để có thêm dữ liệu, đó là tất cả. Nếu bạn muốn đảm bảo dữ liệu được ghi vào tệp một cách an toàn thì hãy sử dụng close () để thay thế.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.