EWOULDBLOCK خطأ مكافئ ضمن Windows Perl
-
02-07-2019 - |
سؤال
يوم سعيد ستاكوفر فلاورز,
أنا مؤلف كتاب بيرل 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 الذي تمت كتابته على الإطلاق سيتوقف عن العمل، لذلك لا أعتقد أنه ستكون هناك مشكلة في تشفيره.