سؤال

بشكل عام، ماذا يمكننا أن نأخذ أمرا مفروغا منه عند إلحاق ملف في UNIX من عمليات متعددة؟ هل من الممكن أن تفقد البيانات (عملية واحدة الكتابة فوق تغييرات الآخرين)؟ هل من الممكن للبيانات الحصول على مشارش؟ (على سبيل المثال، تلبي كل عملية سطر واحد لكل إلحاق إلى ملف السجل، هل من الممكن أن يتم تشكيل سطرين؟) إذا كان التطبيق ليس عطري بالمعنى أعلاه، فما هي أفضل طريقة لضمان الاستبعاد المتبادل؟

هل كانت مفيدة؟

المحلول

من المفترض أن يكون الكتابة الموجودة تحت حجم "pipe_buf" ذرية. يجب أن يكون ذلك 512 بايت على الأقل، على الرغم من أنه قد يكون بسهولة أكبر (يبدو أن Linux تم تعيينه إلى 4096).

هذا يفترض أنك تتحدث كل مكونات متوافقة تماما تماما. على سبيل المثال، هذا ليس صحيحا على NFS.

ولكن على افتراض أنك تكتب إلى ملف السجل الذي فتحته في وضع "O_Append" والحفاظ على خطوطك (بما في ذلك Newline) ضمن "BEAB_BUF" بايت، يجب أن تكون قادرا على الحصول على كتاب متعددين إلى ملف سجل دون أي مشاكل في الفساد. سيصل أي المقاطعات قبل أو بعد الكتابة، وليس في الوسط. إذا كنت تريد تكامل الملفات للبقاء على قيد الحياة لإعادة التشغيل، فستحتاج أيضا إلى الاتصال fsync(2) بعد كل كتابة، ولكن هذا أمر فظيع من أجل الأداء.

توضيح: قراءة التعليقات و إجابة أوقية سليمان. وبعد لست متأكدا من ذلك O_APPEND من المفترض أن يكون ذلك PIPE_BUF حجم الذرية. من الممكن تماما أن مجرد كيفية تنفيذ نظام Linux write(), ، قد يكون بسبب أحجام كتلة نظام الملفات الأساسية.

نصائح أخرى

يحرر: تم التحديث أغسطس 2017 مع أحدث نتائج Windows.

سأقدم لك إجابة مع روابط لاختبار التعليمات البرمجية والنتائج كمؤلف مقترح boost.afio. والتي تنفذ نظام ملفات غير متزامن ومكتبة I / O C ++.

أولا، o_append أو تعادل file_append_data على Windows يعني أن زيادات الحد الأقصى للملف (طول الملف ") الذري تحت الكتاب المتزامنين. هذا مضمون بواسطة posix، ونظام التشغيل Linux، FreeBSD، OS X و Windows ALL ينفذه بشكل صحيح. تقوم سامبا أيضا بتنفيذ ذلك بشكل صحيح، ولا يعمل NFS قبل V5 لأنها تفتقر إلى إمكانية التنسيق الأسلاك لإلحاق ذلك بسطوم. لذلك إذا قمت بفتح الملف الخاص بك مع إلحاق فقط، الكتابة المتزامنة لن تمزق فيما يتعلق ببعضها البعض على أي نظام تشغيل رئيسي ما لم يشارك NFS.

ومع ذلك المتزامن يقرأ إلى الملحقات الذرية مايو انظر الكتب الممزقة اعتمادا على نظام التشغيل، نظام الإيداع، وما هي الأعلام التي فتحتها الملف مع - زيادة الحد الأقصى للمجموع الذرية، ولكن ظهور الوضوح فيما يتعلق بالقراءة قد تكون أو لا تكون ذرية. فيما يلي ملخص سريع بواسطة Flags ونظام التشغيل والنظام التشغيل:


لا o_direct / file_flag_no_buffering:

Microsoft Windows 10 مع NTFS: تحديث Atomicity = 1 بايت حتى وتشمل 10.0.10240، من 10.0.14393 ما لا يقل عن 1 ميغابايت، ربما لا حصر له (*).

Linux 4.2.6 مع Ext4: تحديث البذرة = 1 بايت

FreeBSD 10.2 مع ZFS: تحديث البذر = 1 ميغابايت على الأقل، ربما لا حصر له (*)

o_direct / file_flag_no_buffering:

مايكروسوفت ويندوز 10 مع NTFS: تحديث البذرة = حتى بما في ذلك 10.0.10240 حتى 4096 بايت فقط إذا تمت محاذاة الصفحة، وإلا 512 بايت إذا كان file_flag_write_through خارج، آخر 64 بايت. لاحظ أن هذه الذروة ربما تكون ميزة في PCIE DMA بدلا من تصميمها. منذ 10.0.14393، على الأقل 1 ميغابايت، ربما لانهائي (*).

Linux 4.2.6 مع ext4: تحديث البذر = 1 ميغابايت على الأقل، ربما لا حصر له (*). لاحظ أن Linuxes السابق مع Ext4 بالتأكيد لم يتجاوز 4096 بايت، يستخدم XFS بالتأكيد أن يكون لديك قفل مخصص ولكن يبدو أن Linux الأخيرة قد تم إصلاح هذا أخيرا هذا.

FreeBSD 10.2 مع ZFS: تحديث البذر = 1 ميغابايت على الأقل، ربما لا حصر له (*)


يمكنك أن ترى نتائج اختبار التجريبية الخام في https://github.com/ned14/afio/tree/master/programs/fs-probe.. وبعد ملاحظة نحن نختبر الإزاحة الممزقة فقط على 512 مضاعفات بايت، لذلك لا أستطيع أن أقول ما إذا كان التحديث الجزئي لقطاع بايت 512 سيددم خلال دورة قراءة القراءة.

لذلك، للإجابة على سؤال OP، لن تتداخل O_Append Writes مع بعضها البعض، لكنه يقرأ متزامنا إلى O_Append، ربما سيشاهد الكتب الممزقة على Linux مع Ext4 إلا إذا كان O_Direct قيد التشغيل، حيث ستحتاج الكتب O_Append إلى أن يكون حجم القطاع المتعدد.


(*) "ربما لا حصر له" ينبع من هذه البنود في مواصفات posix:

يجب أن تكون جميع الوظائف التالية ذرية فيما يتعلق ببعضها البعض في الآثار المحددة في posix.1-2008 عندما يعملون على الملفات العادية أو الروابط الرمزية ... [العديد من الوظائف] ... قراءة () ... كتابة ( ) ... إذا كان كل من الخيوط الخاصة به كل مكالمة واحدة من هذه الوظائف، فإن كل مكالمة إما أن ترى كل الآثار المحددة للمكالمة الأخرى، أو لا أحد منهم. مصدر

و

يمكن تسلسل الكتابة فيما يتعلق بالقراءة الأخرى والكتابة. إذا ثبت أن قراءة () من بيانات الملفات (بأي وسيلة) تحدث بعد كتابة () من البيانات، يجب أن تعكس الكتابة ()، حتى لو تم إجراء المكالمات بواسطة عمليات مختلفة. مصدر

ولكن على العكس:

لا يحدد حجم Posix.1-2008 هذا السلوك للكتابة المتزامنة إلى ملف من عمليات متعددة. يجب أن تستخدم التطبيقات شكلا من أشكال التحكم في التزامن. مصدر

يمكنك قراءة المزيد عن معنى هذه الإجابة

كتبت نصا إلى اختبار تجريبيا الحد الأقصى لحجم الملحق الذرية. ينتشر البرنامج النصي، المكتوبة في BASH، بعمليات متعددة العمال التي تكتب جميع التواقيع الخاصة بالعمل في نفس الملف. ثم يقرأ الملف، والبحث عن توقيعات متداخلة أو تالفة. يمكنك رؤية المصدر للسيناريو في هذا مشاركة مدونة.

تختلف الحد الأقصى الفعلي للحجم الوظيفة الذرية ليس فقط عن طريق نظام التشغيل، ولكن بواسطة نظام الملفات.

على Linux + ext3 الحجم 4096، وعلى نظام التشغيل Windows + NTFS الحجم هو 1024. انظر التعليقات أدناه للحصول على المزيد من الأحجام.

هنا هو ما يقوله المعيار: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html..

إذا كان O_APPEND Flag من أعلام حالة مصطلحات، يجب تعيين ملف إزاحة الملف في نهاية الملف قبل كل كتابة وعدم حدوث عملية تعديل الملفات الفاصلة بين تغيير إزاحة الملف وعملية الكتابة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top