Điều gì xảy ra khi bạn đọc một tập tin trong khi nó bị ghi đè?


26

Giả sử tôi đọc (cat) một tập tin trong khi một quá trình khác đang viết lại nội dung của nó. Là đầu ra dự đoán? Chuyện gì sẽ xảy ra?


3
Hành vi không xác định, bạn không bao giờ nên làm điều này.
cúc

Câu trả lời:


19

Điều đó phụ thuộc vào những gì người viết làm.

Nếu người viết ghi đè lên tệp hiện có, thì người đọc sẽ thấy nội dung mới khi người viết vượt qua người đọc, nếu có. Nếu người viết và người đọc tiến hành ở tốc độ thay đổi, người đọc có thể thay thế xem nội dung cũ và mới.

Nếu người viết cắt bớt tệp trước khi nó bắt đầu ghi, trình đọc sẽ chạy ngược lại phần cuối của tệp tại thời điểm đó.

Nếu người viết tạo một tệp mới sau đó chuyển tệp mới sang tên cũ, người đọc sẽ tiếp tục đọc từ tệp cũ. Nếu một tệp đã mở được di chuyển hoặc xóa, các quy trình có tệp được mở sẽ tiếp tục đọc từ cùng một tệp đó. Nếu tệp bị xóa, nó thực sự vẫn còn trên đĩa (nhưng không có cách nào để mở lại) cho đến khi quá trình cuối cùng đã đóng nó.

Các hệ thống Unix có xu hướng không có các khóa bắt buộc . Nếu một ứng dụng muốn đảm bảo rằng thành phần nhà văn và thành phần đầu đọc của nó không giẫm lên các ngón chân của nhau, thì nhà phát triển sẽ sử dụng khóa thích hợp. Có một vài trường hợp ngoại lệ trong đó một tệp được mở bởi kernel có thể được bảo vệ khỏi việc ghi bởi các ứng dụng người dùng, ví dụ như hình ảnh hệ thống tập tin vòng lặp hoặc một tệp thực thi được thực thi trên một số biến thể unix.


Gilles, giải thích của bạn cũng áp dụng trong ftp/ sftpkịch bản? Giả sử một quá trình bắt đầu đọc một ftptệp được truyền trong khi một phiên bản khác của cùng một tệp đang ghi đè lên nó do một truyền mới.
iruvar

@ 1_CR Có. Trong trường hợp đó, người viết và người đọc là các quá trình ftpd.
Gilles 'SO- ngừng trở nên xấu xa'

ý nghĩa của việc vượt qua ở đây là gì?
Victor Choy

@VictorChoy Ý nghĩa tiêu chuẩn: bắt đầu phía sau / sau người khác và đến một lúc nào đó hãy tiến lên phía trước họ.
Gilles 'SO- ngừng trở thành ác quỷ '10

18

Đó là một điều kiện cuộc đua cổ điển, do đó, kết quả là không thể đoán trước theo định nghĩa.

Trong số những người khác, nó phụ thuộc vào

  • fopen(3)hoặc open(2)viết chế độ,
  • Làm thế nào / nếu người viết đang đệm đầu ra của nó,
  • người đọc đang đọc tập tin như thế nào
  • sự khác biệt tốc độ giữa người đọc và nhà văn,
  • sự khác biệt về thời gian giữa sự bắt đầu của người đọc và người viết.
  • Và tất nhiên, trên các máy đa lõi hiện đại, mọi thứ thậm chí còn phức tạp hơn bởi các yếu tố khác thấp hơn (ví dụ lập lịch trình quy trình).

Nếu bạn cần có thể đọc một tập tin trong khi nó đang được viết lại, thì bạn có thể khiến người viết tạo một bản sao tạm thời của tập tin, sửa đổi nó, sau đó sao chép nó trở lại tập tin gốc. Đây là cách rsynclàm điều này, ví dụ. Có một số cách để thực hiện điều này, nhưng không có bữa trưa miễn phí. Mỗi phương pháp đều có những thiếu sót và tác động riêng.


1
Câu trả lời này là toàn diện hơn nhiều so với của tôi. Xóa câu trả lời của tôi.
sát thủ

0

Những người trả lời trước có nhiều lời giải thích toàn diện hơn điều này, nhưng đây là một mẹo chắc chắn cũng hoạt động tốt, thực hiện khá nhiều thứ anh ta muốn:

$ tail -f <filename>

Sẽ cho bạn thấy phần cuối của tập tin khi nó được viết. Tiện dụng nếu bạn muốn chuyển STDERR sang một tệp nhưng vẫn thấy nó trong một cửa sổ đầu cuối khác, ví dụ.

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.