Chỉnh sửa: Cập nhật tháng 8 năm 2017 với kết quả Windows mới nhất.
Tôi sẽ cung cấp cho bạn câu trả lời với các liên kết đến mã kiểm tra và kết quả với tư cách là tác giả của Boost.AFIO được đề xuất triển khai hệ thống tệp không đồng bộ và thư viện tệp i / o C ++.
Thứ nhất, O_APPEND hoặc FILE_APPEND_DATA tương đương trên Windows có nghĩa là số gia tăng của phạm vi tệp tối đa ("độ dài" của tệp) là nguyên tử đối với người viết đồng thời. Điều này được đảm bảo bởi POSIX và Linux, FreeBSD, OS X và Windows đều triển khai nó một cách chính xác. Samba cũng thực hiện nó một cách chính xác, NFS trước v5 không có vì nó thiếu khả năng định dạng dây để nối nguyên tử. Vì vậy, nếu bạn mở tệp của mình bằng append-only, việc ghi đồng thời sẽ không bị xé lẫn nhau trên bất kỳ hệ điều hành chính nào trừ khi có NFS.
Tuy nhiên, việc đọc đồng thời đối với các phần bổ sung nguyên tử có thể thấy các bản ghi bị rách tùy thuộc vào hệ điều hành, hệ thống lưu trữ và bạn đã mở tệp bằng cờ nào - mức tăng của mức tối đa của tệp là nguyên tử, nhưng khả năng hiển thị của các lần ghi đối với lần đọc có thể có hoặc không là nguyên tử. Đây là bản tóm tắt nhanh theo cờ, hệ điều hành và hệ thống lưu trữ:
Không O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 với NTFS: cập nhật nguyên tử = 1 byte cho đến và bao gồm 10.0.10240, từ 10.0.14393 tối thiểu 1Mb, có thể là vô hạn (*).
Linux 4.2.6 với ext4: update nguyên tử = 1 byte
FreeBSD 10.2 với ZFS: cập nhật nguyên tử = ít nhất 1Mb, có thể là vô hạn (*)
O_DIRECT / FILE_FLAG_NO_BUFFERING:
Microsoft Windows 10 với NTFS: update atomity = cho đến khi và bao gồm 10.0.10240 lên đến 4096 byte chỉ khi căn chỉnh trang, nếu không 512 byte nếu tắt FILE_FLAG_WRITE_THROUGH, còn lại 64 byte. Lưu ý rằng tính nguyên tử này có thể là một tính năng của PCIe DMA hơn là được thiết kế trong. Kể từ 10.0.14393, ít nhất 1Mb, có thể là vô hạn (*).
Linux 4.2.6 với ext4: update nguyên tử = ít nhất 1Mb, có thể là vô hạn (*). Lưu ý rằng các Linux trước đó với ext4 chắc chắn không vượt quá 4096 byte, XFS chắc chắn đã từng có khóa tùy chỉnh nhưng có vẻ như Linux gần đây cuối cùng đã khắc phục điều này.
FreeBSD 10.2 với ZFS: cập nhật nguyên tử = ít nhất 1Mb, có thể là vô hạn (*)
Bạn có thể xem kết quả thử nghiệm thực nghiệm thô tại https://github.com/ned14/afio/tree/master/programs/fs-probe . Lưu ý rằng chúng tôi kiểm tra các hiệu số bị rách chỉ trên bội số 512 byte, vì vậy tôi không thể nói liệu bản cập nhật một phần của khu vực 512 byte có bị rách trong chu kỳ đọc-sửa đổi-ghi hay không.
Vì vậy, để trả lời câu hỏi của OP, O_APPEND ghi sẽ không can thiệp vào nhau, nhưng đọc đồng thời với O_APPEND ghi có thể sẽ thấy ghi bị rách trên Linux với ext4 trừ khi O_DIRECT được bật, trong đó O_APPEND ghi của bạn sẽ cần phải là bội số kích thước khu vực.
(*) "Có thể là vô hạn" bắt nguồn từ các mệnh đề này trong thông số kỹ thuật POSIX:
Tất cả các hàm sau đây sẽ là nguyên tử đối với nhau trong các hiệu ứng được chỉ định trong POSIX.1-2008 khi chúng hoạt động trên các tệp thông thường hoặc các liên kết tượng trưng ... [nhiều hàm] ... read () ... write ( ) ... Nếu mỗi luồng gọi một trong các hàm này, thì mỗi lệnh gọi sẽ thấy tất cả các tác dụng được chỉ định của lệnh gọi kia, hoặc không có tác dụng nào trong số chúng. [Nguồn]
và
Các bài viết có thể được đăng nhiều kỳ liên quan đến các bài đọc và viết khác. Nếu việc đọc () dữ liệu tệp có thể được chứng minh (bằng bất kỳ cách nào) xảy ra sau khi ghi () dữ liệu, thì nó phải phản ánh việc ghi () đó, ngay cả khi các lệnh gọi được thực hiện bởi các quy trình khác nhau. [Nguồn]
nhưng ngược lại:
Tập POSIX.1-2008 này không chỉ định hành vi ghi đồng thời vào một tệp từ nhiều quy trình. Các ứng dụng nên sử dụng một số hình thức kiểm soát đồng thời. [Nguồn]
Bạn có thể đọc thêm về ý nghĩa của những điều này trong câu trả lời này
fsync(2)
đảm bảo nhiều nhưsync(2)
vậy và không có nhiều tác động lớn đến hiệu suất.