تخطيط الذاكرة

 

تخطيط الذاكرة

داية التعيين على النجاح أو MAP_FAILED عند الخطأ.

يمكن أن يكون عنوان العنوان الظاهري محددًا من قِبل المستخدم أو تم إنشاؤه بواسطة kernel (عند تمرير العنوان كـ NULL). يتطلب طول الحقل المشار إليه حجم التعيين بالبايت. يشير الحقل prot إلى قيم حماية الذاكرة مثل PROT_NONE و PROT_READ و PROT_WRITE و PROT_EXEC والمقصود بالمناطق التي لا يمكن الوصول إليها أو قراءتها أو كتابتها أو تنفيذها على التوالي. يمكن أن تكون هذه القيمة مفردة (PROT_NONE) أو يمكن أن تكون ORd مع أي من العلامات الثلاثة (آخر 3). تشير إشارات الحقول إلى نوع التعيين إما MAP_PRIVATE أو MAP_SHARED. يشير الحقل "fd" إلى واصف الملف الذي يحدد الملف المراد تعيينه ويشير الحقل "الإزاحة" إلى نقطة البداية للملف ، إذا كنت بحاجة إلى تعيين الملف بأكمله ، فيجب أن تكون الإزاحة صفرًا.

#include <sys/mman.h>

int munmap(void *addr, size_t length);

إرجاع استدعاء النظام أعلاه 0 عند النجاح أو -1 عند الخطأ.

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

دعونا ننظر في مثال -

الخطوة 1 - أدخل ملفًا بأحرف ألفا الرقمية كما هو موضح أدناه -

012...2526272829303132333435363738...596061
أبج...ض0123456789أبج...xذض

الخطوة 2 - قم بتعيين محتويات الملف في الذاكرة باستخدام استدعاء نظام mmap (). سيعيد هذا عنوان البداية بعد تعيينه في الذاكرة.

الخطوة 3 - الوصول إلى محتويات الملف باستخدام تدوين المصفوفة (يمكن أيضًا الوصول إليه باستخدام تدوين المؤشر) لأنه لا يقرأ استدعاء نظام القراءة باهظة الثمن (). باستخدام تعيين الذاكرة ، تجنب النسخ المتعدد بين مساحة المستخدم والمخازن المؤقتة لمساحة kernel وذاكرة التخزين المؤقت.

الخطوة 4 - كرر قراءة محتويات الملف حتى يدخل المستخدم "-1" (يشير إلى نهاية الوصول).

الخطوة 5 - تنفيذ أنشطة التنظيف ، مثل إلغاء تعيين منطقة الذاكرة المعينة (munmap ()) ، وإغلاق الملف وإزالة الملف.

/* Filename: mmap_test.c */
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
void write_mmap_sample_data();

int main() {
   struct stat mmapstat;
   char *data;
   int minbyteindex;
   int maxbyteindex;
   int offset;
   int fd;
   int unmapstatus;
   write_mmap_sample_data();
   if (stat("MMAP_DATA.txt", &mmapstat) == -1) {
      perror("stat failure");
      return 1;
   }
   
   if ((fd = open("MMAP_DATA.txt", O_RDONLY)) == -1) {
      perror("open failure");
      return 1;
   }
   data = mmap((caddr_t)0, mmapstat.st_size, PROT_READ, MAP_SHARED, fd, 0);
   
   if (data == (caddr_t)(-1)) {
      perror("mmap failure");
      return 1;
   }
   minbyteindex = 0;
   maxbyteindex = mmapstat.st_size - 1;
   
   do {
      printf("Enter -1 to quit or ");
      printf("enter a number between %d and %d: ", minbyteindex, maxbyteindex);
      scanf("%d",&offset);
      if ( (offset >= 0) && (offset <= maxbyteindex) )
      printf("Received char at %d is %c\n", offset, data[offset]);
      else if (offset != -1)
      printf("Received invalid index %d\n", offset);
   } while (offset != -1);
   unmapstatus = munmap(data, mmapstat.st_size);
   
   if (unmapstatus == -1) {
      perror("munmap failure");
      return 1;
   }
   close(fd);
   system("rm -f MMAP_DATA.txt");
   return 0;
}

void write_mmap_sample_data() {
   int fd;
   char ch;
   struct stat textfilestat;
   fd = open("MMAP_DATA.txt", O_CREAT|O_TRUNC|O_WRONLY, 0666);
   if (fd == -1) {
      perror("File open error ");
      return;
   }
   // Write A to Z
   ch = 'A';
   
   while (ch <= 'Z') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   // Write 0 to 9
   ch = '0';
   
   while (ch <= '9') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   // Write a to z
   ch = 'a';
   
   while (ch <= 'z') {
      write(fd, &ch, sizeof(ch));
      ch++;
   }
   close(fd);
   return;
}

انتاج |

Enter -1 to quit or enter a number between 0 and 61: 3 
Received char at 3 is D 
Enter -1 to quit or enter a number between 0 and 61: 28
Received char at 28 is 2 
Enter -1 to quit or enter a number between 0 and 61: 38 
Received char at 38 is c 
Enter -1 to quit or enter a number between 0 and 61: 59 
Received char at 59 is x 
Enter -1 to quit or enter a number between 0 and 61: 65 
Received invalid index 65 
Enter -1 to quit or enter a number between 0 and 61: -99 
Received invalid index -99 
Enter -1 to quit or enter a number between 0 and 61: