سؤال

يوم سعيد ستاكوفر فلاورز,

أنا مؤلف كتاب بيرل com.autodie pragma، الذي يغير مكونات Perl المضمنة لطرح استثناءات عند الفشل.انها مماثلة ل مميت, ، ولكن مع النطاق المعجمي، ونموذج الاستثناء القابل للتوسيع، والتحقق من الإرجاع الأكثر ذكاءً، ورسائل خطأ أجمل بكثير.سوف يحل محل Fatal الوحدة النمطية في الإصدارات المستقبلية من Perl (مؤقتًا 5.10.1+)، ولكن يمكن تنزيلها حاليًا من CPAN لـ Perl 5.8.0 وما فوق.

الإصدار القادم من autodie سيضيف معالجة خاصة للمكالمات إلى flock مع ال LOCK_NB خيار (عدم الحظر).بينما فشل flock عادةً ما يؤدي الاتصال إلى استثناء ضمن autodie, ، فشل الاتصال بـ flock استخدام LOCK_NB سيعود فقط كاذبة إذا كان الخطأ الذي تم إرجاعه ($!) يكون EWOULDBLOCK.

والسبب في ذلك هو أن الأشخاص يمكنهم الاستمرار في كتابة التعليمات البرمجية مثل:

use Fcntl qw(:flock);

use autodie;   # All perl built-ins now succeed or die.

open(my $fh, '<', 'some_file.txt');

my $lock = flock($fh, LOCK_EX | LOCK_NB);  # Lock the file if we can.

if ($lock) {
    # Opportuntistically do something with the locked file.
}

في الكود أعلاه، فشل القفل لأن الملف مقفل بالفعل بواسطة شخص آخر (EWOULDBLOCK) لا يعتبر خطأً فادحًا، لذا فإن التشغيل التلقائي flock مجرد إرجاع قيمة خاطئة.في الحالة التي نعمل فيها مع نظام ملفات لا يدعم أقفال الملفات، أو نظام ملفات على الشبكة وتوقفت الشبكة للتو، فإن ذلك يحدث تلقائيًا flock يُنشئ استثناءً مناسبًا عندما يرى أن خطأنا ليس كذلك EWOULDBLOCK.

يعمل هذا بشكل جيد في إصدار التطوير الخاص بي على الأنظمة التي تعمل بنظام Unix، لكنه يفشل بشكل فظيع في نظام Windows.يبدو أنه بينما يدعم Perl ضمن نظام التشغيل Windows ملف LOCK_NB الخيار، فإنه لا يحدد EWOULDBLOCK.بدلاً من ذلك، الخطأ الذي تم إرجاعه هو 33 ("خطأ في المجال") عند حدوث الحظر.

من الواضح أنني أستطيع ترميز هذا باعتباره ثابتًا في autodie, ، ولكن هذا ليس ما أريد أن أفعله هنا، لأنه يعني أنني سأفشل إذا تغير الخطأ (أو تغير).أرغب في مقارنته بما يعادله من Windows POSIX::EWOULDBLOCK, ، لكنني لا أستطيع أن أجد طوال حياتي أين يمكن تعريف مثل هذا الشيء.إذا كنت تستطيع المساعدة، اسمحوا لي أن أعرف.

الإجابات التي لا أريدها على وجه التحديد:

  • اقتراحات لتشفيره كرقم ثابت (أو الأسوأ من ذلك، ترك رقم سحري عائمًا).
  • لا يدعم LOCK_NB وظائف على الإطلاق تحت ويندوز.
  • على افتراض أن أي فشل من أ LOCK_NB دعوة ل flock يجب أن يعود مجرد كاذبة.
  • الاقتراحات التي أطرحها على p5p أو بيرلمونكس.أنا أعرف بالفعل عنهم.
  • شرح لكيفية flock, أو استثناءات أو Fatal عمل.اعرف ذلك مسبقا.متصل عاطفيا.
هل كانت مفيدة؟

المحلول

ضمن Win32 "الأصلي" Perl، لاحظ أن $^E أكثر وصفًا في 33، "لا يمكن للعملية الوصول إلى الملف لأن عملية أخرى قامت بتأمين جزء من الملف" وهو ERROR_LOCK_VIOLATION (متاح من Win32::WinError).

نصائح أخرى

بالنسبة لرمز الخطأ الخاص بنظام التشغيل Windows، الذي تريد استخدامه $^E.في هذه الحالة هو 33:"لا يمكن للعملية الوصول إلى الملف لأن عملية أخرى قامت بتأمين جزء من الملف" (ERROR_LOCK_VIOLATION في winerror.h).

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

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