سؤال

على دخول ويكيبيديا المخزن المؤقت حلقة, ، هناك رمز مثال إظهار الاختراق ل يونيكس الأنظمة التي تكون فيها الذاكرة الافتراضية المجاورة لقطعة من الذاكرة تعيين لنفس الذاكرة phbysical ، وبالتالي تنفيذ المخزن المؤقت حلقة دون الحاجة إلى أي memcpy, ، إلخ. كنت أتساءل عما إذا كان هناك طريقة مماثلة شبابيك?

شكرا ، فريزر

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

المحلول

لم أتابع حقًا جميع تفاصيل المثال في ويكيبيديا. مع وضع ذلك في الاعتبار ، تقوم بتخطيط الذاكرة في Windows باستخدام CreateFileMapping و MapViewoffile, ، ومع ذلك ، لا يسمح لك MapViewOffile بتحديد عنوان أساسي للرسم البياني. MapViewoffileex يمكن استخدامها لتحديد عنوان أساسي ، لذلك ربما يمكنك استخدام تقنية مماثلة.

ليس لدي أي وسيلة لمعرفة ما إذا كان هذا سينجح بالفعل:

// determine valid buffer size
SYSTEM_INFO info;
GetSystemInfo(&info);

// note that the base address must be a multiple of the allocation granularity
DWORD bufferSize=info.dwAllocationGranularity;

HANDLE hMapFile = CreateFileMapping(
             INVALID_HANDLE_VALUE,
             NULL,
             PAGE_READWRITE,
             0,
             bufferSize*2,
             L"Mapping");

BYTE *pBuf = (BYTE*)MapViewOfFile(hMapFile,
                    FILE_MAP_ALL_ACCESS,
                    0,                   
                    0,                   
                    bufferSize);
MapViewOfFileEx(hMapFile,
                    FILE_MAP_ALL_ACCESS,
                    0,                   
                    0,                   
                    bufferSize,
                    pBuf+bufferSize);

نصائح أخرى

أوه مهلا ، هذا هو الموضوع الذي يقلقني كثيرًا مؤخرًا. كنت بحاجة إلى عازلة حلقة محسنة على Posix على Windows ، معظمها بسبب واجهة الوصول العشوائية ، ولكن لم يكن لديها أي فكرة عن كيفية تنفيذها. الآن ، يعمل الكود الذي اقترحته @1800 معلومات في بعض الأحيان ، وأحيانًا لا يعمل ، لكن الفكرة رائعة على أي حال.

الشيء هو، MapViewOfFileEx في بعض الأحيان يفشل مع error_invalid_address مما يعني أنه لا يمكن تعيين طريقة العرض pBuf+bufferSize. هذا لأن ال MapViewOfFile يسمى قبل تحديد مساحة عنوان مجانية bufferSize الطول (بدءا من pBuf) ، لكنه لا يحصل على مساحة العنوان هذه bufferSize*2 طويل. ولماذا نحتاج bufferSize*2 ذاكرة افتراضية؟ لأن المخزن المؤقت حلقة لدينا يحتاج إلى الالتفاف. هذا هو ما هو عرض رسم الخرائط الثاني ل. عندما يترك مؤشر القراءة أو الكتابة العرض الأول ، فإنه يدخل العرض الثاني (لأنها متوفرة في الذاكرة) ، لكنها في الواقع تبدأ من جديد في نفس الخرائط.

UINT_PTR addr;
HANDLE hMapFile;
LPVOID address, address2;

hMapFile = CreateFileMapping (    // create a mapping backed by a pagefile
    INVALID_HANDLE_VALUE,
    NULL,
    PAGE_EXECUTE_READWRITE,
    0,
    bufferSize*2,
    "Local\\mapping" );
if(hMapFile == NULL) 
    FAIL(CreateFileMapping);

address = MapViewOfFile (    // find a free bufferSize*2 address space
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize*2 );
if(address==NULL) 
    FAIL(MapViewOfFile);
UnmapViewOfFile(address);
// found it. hopefully it'll remain free while we map to it

addr = ((UINT_PTR)address);
address = MapViewOfFileEx (
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize, 
    (LPVOID)addr );

addr = ((UINT_PTR)address) + bufferSize;        
address2 = MapViewOfFileEx (
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize,
    (LPVOID)addr);  

if(address2==NULL)      
    FAIL(MapViewOfFileEx);

// when you're done with your ring buffer, call UnmapViewOfFile for 
// address and address2 and CloseHandle(hMapFile)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top