مع SendFile () ، هل من الممكن معرفة متى يكون IN_FD في EOF؟

StackOverflow https://stackoverflow.com/questions/3697002

سؤال

القراءة من خلال صفحة MAN من مكالمة نظام Linux sendfile, ، أتساءل ما إذا كان من الممكن لبرنامج الاتصال معرفة متى in_fd هو في EOF. من المفترض ، يمكن الإشارة إلى هذا من خلال قيمة إرجاع من 0 ، ولكن هذا يؤدي إلى مسألة ما تعنيه قيمة إرجاع 0 بالفعل. إذا sendfile يشبه write, ، ثم تعني قيمة الإرجاع من 0 أنه تم نسخ 0 بايت. لكن اذا sendfile يشبه read, ، ثم قيمة الإرجاع من 0 تعني EOF. يجب على المرء أن يعرف مقدمًا كم عدد البايتات التي سيتم نسخها من in_fd إلى out_fd لكي تستخدم sendfile؟ ماذا يعني متى sendfile يعود 0؟

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

المحلول

لا أعتقد أن هناك طريقة مباشرة لمعرفة ذلك ولكن لا ينبغي أن يكون مهمًا حقًا. عادة ستجد حجم ملف الإدخال عبر stat/fstat واستخدم ذلك لحساب النقل الخاص بك. لن تكون نهاية المقبس مهمة لك.

الموقف الوحيد الذي يجب أن يكون هذا مشكلة هو إذا كنت تريد نقل ملف ينمو أو يتقلص. بالنظر إلى أن ملف الإدخال يجب أن يكون MMAP-ED ، والأشياء السيئة التي يمكن أن تحدث (بدون بعض التعليمات البرمجية الذكية) مع MMAP في تلك المواقف التي ربما لا ينبغي أن تستخدم SENDFILE لتلك الحالات.

نصائح أخرى

يمكنك استخدام معلمة الإزاحة لقراءة عدد القراءة.

وفقا لصفحة الرجل

إذا لم يكن الإزاحة فارغة ، فإنه يشير إلى متغير يحمل إزاحة الملف التي سيبدأ منها SendFile () في قراءة البيانات من IN_FD. عند عودة SendFile () ، سيتم ضبط هذا المتغير على إزاحة البايت بعد البايت الأخير الذي تمت قراءته. إذا لم يكن الإزاحة فارغة ، فإن SendFile () لا يعدل إزاحة الملف الحالي لـ IN_FD ؛ وإلا يتم تعديل إزاحة الملف الحالية لتعكس عدد البايتات القراءة من in_fd.

العد هو عدد البايتات للنسخ بين واصفات الملف.

قيمة الإرجاع إذا كان النقل ناجحًا ، يتم إرجاع عدد البايتات المكتوبة إلى Out_FD. عند الخطأ ، يتم إرجاع -1 ، ويتم تعيين Errno بشكل مناسب.

ونعم هذا يعني أن قيمة الإرجاع 0 تعني عدم نسخ البيانات لكتابة المقبس.

يمكنك أن تفترض أن EOF قد تم الوصول إليه عندما يكون عدد البايتات المرسلة هو 0:

sent = sendfile(out_fd, in_fd, &offset, nbytes);
if (sent == 0) {
    // EOF
    ...
}

هذا الافتراض يعمل أيضا في حالة مآخذ غير الحظر.

في حالتي ، يتم تقسيم الملف بواسطة RSYNC ، استخدم التطبيق SendFile لنقل الملف في نفس الوقت. أجد أن APP Eat CPU 100 ٪ في الحالة ، أقوم بإصلاح الكود الخاص بي ، راجع المقالة المتابعة ، ويختفي السؤال.http://www.linuxjournal.com/article/6345

النقطة هي استخدام f_setLease احصل على تأجير الملفات لتطبيقك.

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