عمليات المتزامن مع I / O الموانئ استكمال عودة 0 بايت نقل

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

سؤال

والعمليات غير متزامن مع I / O الموانئ استكمال تعود 0 بايت نقل، على الرغم من أن عمليات I / O تعمل كما هو متوقع (بلدي مخازن قراءة تصبح كاملة).

BYTE buffer[1024] = {0};
OVERLAPPED o = {0};
HANDLE file = CreateFile(
    _T("hello.txt"),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
);
HANDLE completion_port = CreateIoCompletionPort(
    file,
    NULL,
    0,
    0
);
ReadFile(
    file,
    buffer,
    1024,
    NULL,
    &o
);

في موضوع العمل:

DWORD numBytes = 0;
LPOVERLAPPED po;
GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    0,
    &po,
    INFINITE
);
GetOverlappedResult(file, &o, &numBytes, FALSE);

وكلا الدالات بإرجاع 0 بايت في numBytes، ولكن buffer وملء. هذا السلوك المتوقع؟

وشكرا.

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

المحلول

لGetIoCompletionPort للعمل بشكل صحيح، تحتاج إلى تحديد مؤشر غير الصفرية إلى ULONG_PTR لذلك لكتابة قيمة 'الرئيسية' ل:

ULONG_PTR key;

GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    &key,
    &po,
    INFINITE
);

لاستخدام GetOverlappedResult بنجاح، وأعتقد أنك في حاجة لتحديد معالجة حدث في بنية OVERLAPPED (موصى به بقوة على أي حال):

o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

واستدعاء اثنين في الخلافة كما كنت لا تنجز كثيرا في الواقع - كلاهما اقول لكم عن نفس الأشياء. رغم ذلك إذا كنت تفعل الكلمة سواء في الخلافة، سوف تحتاج إلى تغيير حدث ليكون يدوية إعادة تعيين عن طريق تغيير المعلمة الثالث لCreateEvent إلى TRUE. تخميني هو أن كنت مجرد محاولة على حد سواء لمعرفة ما إذا كان يمكن أن تحصل واحد للعمل. كل الأمور في الاعتبار، ربما كنت مجرد استخدام GetQueuedCompletionStatus، وترك الأمر عند هذا الحد. بطبيعة الحال، سوف تفعل عادة أكثر من يطلق عليه مرة واحدة والإقلاع عن التدخين. استدعاء عادة في حلقة، وتجهيز المخزن المؤقت الحالي كنت قد قرأت، ثم استدعاء ReadFile مرة أخرى لقراءة عازلة آخر من المعلومات، شيء من هذا القبيل:

DWORD numBytes;
LPOVERLAPPED po;
while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) {
    std::cout << "\rRead: " << numBytes; // just to show it's set correctly.
    process(buffer);
    po->offset += sizeof(buffer);
    ReadFile(file, buffer, sizeof(buffer), NULL, po);
}

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

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