LINUX.ORG.RU

memory mapped файл


0

2
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<iostream>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/mman.h>

/* Ниже следует описание типа структуры, которым мы забьем
файл, и двух указателей на подобный тип. Указатель ptr
будет использоваться в качестве начального адреса 
выделенной области памяти, а указатель tmpptr – для 
перемещения внутри этой области. */
struct A {
    double f;
    double f2;
};

int main()
{
    int fd; /* Файловый дескриптор для файла, в 
котором будет храниться наша информация*/
    size_t length; /* Длина отображаемой части файла */
    int i; 
A *ptr, *tmpptr;
    /* Открываем файл или сначала создаем его (если 
такого файла не было). Права доступа к файлу при создании 
определяем как read-write для всех категорий пользователей 
(0666). Из-за ошибки в Linux мы будем вынуждены ниже в 
системном вызове mmap() разрешить в отображении файла и 
чтение, и запись, хотя реально нам нужна только запись. 
Поэтому и при открытии файла мы вынуждены задавать O_RDWR. */
    fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);
    if( fd == -1){
        /* Если файл открыть не удалось, выдаем 
сообщение об ошибке и завершаем работу */
        printf("File open failed!\n");
        exit(1);
    }
    /* Вычисляем будущую длину файла (мы собираемся записать
    в него 100000 структур) */
    length = 100000*sizeof(struct A);
    /* Вновь созданный файл имеет длину 0. Если мы его 
    отобразим в память с такой длиной, то любая попытка 
    записи в выделенную память приведет к ошибке. Увеличиваем
    длину файла с помощью вызова ftruncate(). */
    ftruncate(fd,length);
    /* Отображаем файл в память. Разрешенные операции над
    отображением указываем как PROT_WRITE | PROT_READ по 
    уже названным причинам. Значение флагов ставим в 
    MAP_SHARED, так как мы хотим с охранить информацию, 
    которую занесем в отображение, на диске. Файл 
    отображаем с его начала (offset = 0) и до конца 
    (length = длине файла). */
    ptr = (struct A*)mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    /* Файловый дескриптор нам более не нужен, и мы его
    закрываем */
    close(fd);
    if( ptr == MAP_FAILED ){
        /* Если отобразить файл не удалось, сообщаем об
        ошибке и завершаем работу */
        printf("Mapping failed!\n");
        exit(2);
    }
    /* В цикле заполняем образ файла числами от 1 до 100000
    и их квадратами. Для перемещения по области памяти 
    используем указатель tmpptr, так как указатель ptr на 
    начало образа файла нам понадобится для прекращения 
    иотображения вызовом munmap(). */
    tmpptr = ptr;
    for(i = 1; i <=100000; i++){
        tmpptr->f = i;
        tmpptr->f2 = tmpptr->f * tmpptr->f;
        tmpptr++;
    }
    /* Прекращаем отображать файл в память, записываем 
    содержимое отображения на диск и освобождаем память. */
    munmap((void *)ptr, length);
    return 0;
}

Эта программа создает файл, отображает его в адресное пространство процесса и заносит в него информацию с помощью обычных операций языка С.

дали такое задание: Модифицируйте программу из предыдущего раздела так, чтобы она отображала файл, записанный программой из раздела «Анализ, компиляция и прогон программы для создания memory mapped файла и записи его содержимого», в память и считала сумму квадратов чисел от 1 до 100000, которые уже находятся в этом файле. Что то тема для меня сложновато(( Помогите разобратся)

А что конкретно тут сложного?

Dead ★★★★ ()
Ответ на: комментарий от Hunter_nub

Вроде бы в файле который создал первая программа должно быть числа от 1 до 100000 . Но в этом файле каракулы какие то .

Hunter_nub ()
Ответ на: комментарий от Hunter_nub

Так какая именно фраза непонятна? Первый пример создает файл. Во второй программе нужно примапить файл похожим образом (только без его создания) и, работая как с массивом, посчитать то, что требуется.

Dead ★★★★ ()
Ответ на: комментарий от Hunter_nub

Какие каракулы? Там бинарные данные лежат (массив структур).

Dead ★★★★ ()
Ответ на: комментарий от Hunter_nub

«чтобы она отображала файл, в память и считала сумму квадратов чисел от 1 до 100000, которые уже находятся в этом файле» как отобразить этот файл в память ?

Hunter_nub ()
Ответ на: комментарий от Dead

ладно , еще раз пройдусь по теме) а то я совсем не чего не понял)))

Hunter_nub ()
Ответ на: комментарий от Hunter_nub

Также как и в первом примере. open() + mmap() только open() будет немного с другими параметрами (только на чтение).

Dead ★★★★ ()
Ответ на: комментарий от Dead

А вообще связка open() + mmap() будет работать абсолютно такая же, как и в первом примере.

Dead ★★★★ ()

разделом ошибся, нужно в jobs.

Развернутая версия:

так сформулированный вопрос это только решение за деньги, ну или суперхаккиллер ответит. Если ты хочешь, чтобы тебе помогли - проведи работу сам и докажи, что готов учиться. Например, покажи, что читал, чтот пытался сделать и какие у тебя _конкретные_ вопросы.

qnikst ★★★★★ ()
Последнее исправление: qnikst (всего исправлений: 1)
Ответ на: комментарий от Hunter_nub

«считала сумму квадратов чисел от 1 до 100000» так нужно сделать?

  for(i = 1; i <=100000; i++){
        tmpptr->f = i;
        tmpptr->f2 = tmpptr->f * tmpptr->f;
        tmpptr++;
summa=+tmpptr->f2;
    }

Hunter_nub ()
Ответ на: комментарий от qnikst

да я сам понимаю, что напрямую просить сделать неправильно))думал, а вдруг сделают))

Hunter_nub ()
Ответ на: комментарий от Hunter_nub

ага, только три строчки лишние :)

у вас же квадраты уже посчитаны в первом примере.

Dead ★★★★ ()
Ответ на: комментарий от Hunter_nub

ну почему, некоторые могут ответить, напр:

import Control.Monad
import System.IO.MMap
import Data.Vector.Storable as V
import Foreign.Storable

data A = A { aF:: Double, aF2:: Double}

instance Storable A where


main = 
  print . V.sum . V.map aF2 <=<
    fmap (\(fp, i, o) -> V.unsafeFromForeignPtr fp i o)
          $ mmapFileForeignPtr "file" ReadOnly Nothing

здесь правда не хватает записи инстанса storable :)

qnikst ★★★★★ ()

дали такое задание

попроси автора задания срочно зайти на ЛОР.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от Dead
struct A {
    double f;
    double f2;
};

int main()
{
    int fd;   
int summa=0;
  size_t length; /* Длина отображаемой части файла */
    int i; 
A *ptr, *tmpptr;
    fd = open("mapped.dat", O_RDWR, 0666);
    if( fd == -1){
        printf("File open failed!\n");	

        exit(1);
    }
    length = 100000*sizeof(struct A);
    ftruncate(fd,length);
    ptr = (struct A*)mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    close(fd);
    if( ptr == MAP_FAILED ){
        printf("Mapping failed!\n");
        exit(2);
    }
    tmpptr = ptr;
    for(i = 1; i <=100000; i++){
        tmpptr++;
summa=+tmpptr->f2;					
    }
printf("summa = %u\n",summa);
    munmap((void *)ptr, length);
    return 0;
}

вот сделал тока выводит сумма ровна 0. в чем дело?

Hunter_nub ()
Ответ на: комментарий от Hunter_nub

Т.е. ты не понимаешь чем отличаются представление числа в «комутере» и строке? 123 - это не число - это строка, в которой 3символа {'1', '2', '3'}; Каждый из которых сам является числом. В википедии ascii.

Ищи в гугле «представление чесел». Тебе ещё рано говорить про какую-то сишку, код и прочее.

Вот почитаешь, поймёшь чем отличается строка от числа - приходи.

anonymous ()
Ответ на: комментарий от qnikst

По строчкам слил сишке в говно, приэтом нехватает в районе 5000% флопсов. Да и производительность чтения сольёт раз в 10 в лучшем случае. А так да, понтанулся - молодец.

Тыж там мне так и не ответил - ты понял почему твоя функция говно, а не универсальная?

anonymous ()
Ответ на: комментарий от qnikst

зачет, поддержим троллинг:

import mmap
import struct

dat_file = "mapped.dat"   # filename
dat_fmt  = "d"            # entry format, "double" in this case

entry_size = struct.calcsize(dat_fmt) # size of one entry in bytes

with open(dat_file, "r+b") as f:
    with mmap.mmap(f.fileno(), 0) as mm:

        total = 0

        # read each _second_ entry until EOF
        for i in range(0, int(mm.size() / entry_size), entry_size*2):
            total += struct.unpack(dat_fmt, mm[i:i+entry_size])[0]

print(total)
val-amart ★★★★★ ()
Ответ на: комментарий от Hunter_nub

1. Подумай какой тип должен быть у summa.

2. Подумай, что делает строка:

summa=+tmpptr->f2;

Dead ★★★★ ()
Ответ на: комментарий от Hunter_nub

о, это уже похоже хоть на какую-то работу. твои главные строки которые ты добавил:

int summa=0;
summa=+tmpptr->f2;
printf("summa = %u\n",summa);

во-первых, почему инт? во-вторых, у тебя ошибка при суммировании. прочитай внимательно что ты делаешь. напиши еще раз. если не найдешь за полчаса, покажу.

val-amart ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.