التابع IO.write_nonblock‎ في روبي

من موسوعة حسوب

يكتب التابع write_nonblock السلسلة النصية المعطاة في مجرى د/خ الذي استُدعي معه باستخدام استدعاء النظام write(2)‎ بعد تعيين قيمة الراية O_NONBLOCK الخاصة بواصف الملف (file descriptor) الأساسي. ثم يعيد عدد البايتات المكتوبة.

يستدعي التابع write_nonblock استدعاء النظام write(2)‎. ويتسبب في كافة الأخطاء التي يتسبب فيها استدعاء النظام write(2)‎، مثل Errno::EWOULDBLOCK و Errno::EINTR وغيرهما. قد تكون النتيجة أصغر من طول السلسلة النصية (أي أن الكتابة جزئية). لذا يجب أن يعالج المستدعي هذه الأخطاء، إضافة إلى مسألة الكتابة الجزئية.

إن كان الاستثناء يساوي Errno::EWOULDBLOCK أو Errno::EAGAIN، فسيتم توسيعه بواسطة IO::WaitWritable حتى يمكن استخدام IO::WaitWritable لمعالجة الاستثناءات لأجل إعادة استدعاء التابع write_nonblock.

إذا لم يكن المخزن المؤقت (buffer) للكتابة فارغًا، فسيتم نقله (flushed) في البداية.

عندما يطلق التابع write_nonblock استثناءً من النوع IO::WaitWritable، فلا يجب استدعاؤه حتى يكون مجرى د/خ قابلاً للكتابة، لتجنب الحلقات التكرارية. ويمكن القيام بذلك على النحو التالي.

begin
  result = io.write_nonblock(string)
rescue IO::WaitWritable, Errno::EINTR
  IO.select(nil, [io])
  retry
end

لاحظ أن هذا لا يضمن كتابة جميع البيانات في السلسلة النصية. سيتم الإبلاغ عن الطول المكتوب في النتيجة، ويجب فحصه في وقت لاحقًا.

في بعض أنظمة التشغيل, مثل ويندوز، قد لا يكون التابع write_nonblock مدعوما مع بعض أنواع مجاري د/خ. في مثل هذه الحالات، سيُطلق التابعwrite_nonblock الاستثناء Errno::EBADF.

عبر إعطاء الوسيط المسمى (keyword argument)‏ exception القيمة false، يمكنك منع التابع write_nonblock من إطلاق الاستثناء IO::WaitWritable، وجعله يُعيد الرمز:wait_writable بدلاً من ذلك.

البنية العامة

write_nonblock(string) integer
write_nonblock(string [, options]) integer

المعاملات

string‎

سلسلة نصية

options‎

خيارات

القيمة المُعادة

يعيد التابع write_nonblock عدد البايتات المكتوبة.

أمثلة

مثال على استخدام التابع write_nonblock‎:

# Creates a pipe.
r, w = IO.pipe
# write_nonblock writes only 65536 bytes and return 65536.
# (The pipe size is 65536 bytes on this environment.)
s = "a" * 100000
p w.write_nonblock(s)     #=> 65536
# write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
p w.write_nonblock("b")   # Resource temporarily unavailable (Errno::EAGAIN)‎

انظر أيضا

مصادر