سؤال

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

هنا هو رمزي، هل يمكنك أن ترى أي شيء خاطئ في ذلك؟

كود الكائن 1:

 16     FILE* temp = fopen(theSharedFileName, "w");
 17     fseek(temp, fileSize-1, SEEK_SET);
 18     fprintf(temp, "0"); // make the file a certain size
 19     fseek(temp, 0, SEEK_CUR);
 20 
 21     int sharedFileName = fileno(temp);
 ...
 31     sharedArea = (MyStruct*)mmap(0, fileSize,
 32         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, sharedFileName, 0);

يمكنني استخدام وضع الملفات "W" لأن الكائن 1 لن يتم إجراؤه مرة واحدة فقط وأريده إعادة تعيين أي بيانات موجودة مسبقا.

كود كائن 2:

 130     FILE* tempFile = fopen(sharedFileName, "a");
 131     int theFile = fileno(tempFile);
 ...
 135     sharedArea = (MyStruct*)mmap(NULL, fileSize,
 136         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, theFile, 0);
هل كانت مفيدة؟

المحلول

بعض القضايا:

  1. تجنب خلط I / O رفيع المستوى (FOPEN ()، FSEEK ()) وبعض التشغيل المنخفض المستوى مثل mmap (). على الرغم من أنه يمكنك الحصول على واصف الملفات منخفضة المستوى باستخدام Fileno ()، فإن هذا يشبه أخذ أطول طريق للوصول إلى نفس المكان. أيضا، فقط باستخدام MMAP () يكسر التوافق خارج BSD و Posix، لذلك لا تحصل على أي شيء باستخدام وظائف CI / O القياسية. مجرد استخدام فتح () و lseek () مباشرة.
  2. لا معنى له استخدام الدفق التنسيقي I / O (FPRINTF ()) في نفس الملف الذي توجد فيه رسم خرائط الذاكرة. عندما تقوم بالذاكرة خريطة الذاكرة، فأنت تخبر ضمنيا النظام الذي ستستخدمه كبيانات وصول عشوائي (فهرسة مباشر). FPRINTF () مخصص لإخراج الدفق، وعادة ما تستخدمه للوصول المتسلسل. في الواقع، رغم أنه ممكن، فمن غير المعتاد أن نرى FPRINTF () و FSEEK () في نفس الوصف (هذا غير محمول، ولكن بسبب العنصر السابق، أنا لا أفكر في إمكانية النقل).
  3. يجب أن تتطابق الحماية من حماية الملفات المفتوحة. منذ أن تمر "W" إلى FOPEN ()، و PROT_READ | PROT_WRITE | PROT_EXEC إلى MMP ()، أنت تنتهك هذا التقييد. هذا يسلط الضوء أيضا على سبب عدم خلط I / O رفيع المستوى مع تعيين الذاكرة: كيف تضمن ذلك fopen(...,"w") سيتم فتح الملف مع الأعلام الصحيحة؟ من المفترض أن يكون هذا "تفاصيل التنفيذ" لمكتبة C. إذا كنت ترغب في تعيين ملف في الذاكرة مع أذونات القراءة والكتابة، يجب عليك استخدام المستوى المنخفض open(theSharedFileName, O_RDWR) لفتح الملف.
  4. لا استعمال PROT_WRITE و PROT_EXEC سويا او معا. انها ليست المحمولة و إنه مخاطر أمنية. أقرأ عن W ^ X. و حماية الفضاء القابلة للتنفيذ.

نصائح أخرى

إذا كنت تستطيع استخدام C ++ والمكتبات مثل بارع أو تعزيز أن درعك من تفاصيل المستوى المنخفض وتوفير تجريد أسهل ل IPC..

كما قال آخرون، لا تستخدم fopen () والأصدقاء لهذا الغرض.

قد يكون جزء من المشكلة التي تعاني من تواجهها بسبب حقيقة أن FPRINTF () يمكن أن يكون لديك مخازن دفقية، لذلك قد لا يغير الملف بالفعل، وبالتالي تكون مرئية للعملية الأخرى عند المتوقع. يمكنك إضافة fflush ()، ولكن القراءة () والكتابة () لا تفعل أي تخزين مؤقت لمستوى التطبيق، وهو جزء من سبب وجودهم أكثر ملاءمة.

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