Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.76
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
#1

Чтение/запись в файл с использованием многопоточности - C++

06.08.2014, 01:01. Просмотров 2677. Ответов 38
Метки нет (Все метки)

Доброго времени суток!
Хочу решить следующую задачу:
Есть большой бинарный файл (несколько гигабайт к примеру). Нужно разбить этот файл на части и записать в другой файл хэши этих частей, используя многопоточность (многопроцессорность). С ней я никогда не работал. Читал про процессы, потоки и т.д. Но никогда не использовал в программах.
Предполагаю сделать так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "header.h"
using namespace std;
 
void read_file( mutex& m_arr, mutex& m_out) {
    int num;
    
        FILE *fin, *fout;
        size_t k;
        char buf[1024];
        fin = fopen("input.txt", "r");
 
        while (!feof(fin))
        {
            m_arr.lock();
            k = fread(buf, sizeof(char), 100, fin);
    
        }
        fclose(fin);
        
}
void write_file( mutex& m_arr, mutex& m_out) {
    int i = 0, num;
    
}
 
int main()
{
    
    mutex m_arr, m_out;
    thread read_thread(read_file, ref(m_arr), ref(m_out));
    thread write_thread(write_file, ref(m_arr), ref(m_out));
    if (read_thread.joinable()) read_thread.join();
    if (write_thread.joinable()) write_thread.join();
    
    return 0;
}
 
 
}
Думаю, как использовать мьютексы. Был бы признателен за подсказки, как грамотнее реализовать эту задачу. Может быть дробление, чтение файла лучше реализовывать по другому? Или многопоточность использовать по другому? Пока я предполагал, что один поток будет читать и дробить в файлы, другой хэшировать и записывать. Заранее спасибо!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.08.2014, 01:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Чтение/запись в файл с использованием многопоточности (C++):

Чтение и запись в файл - C++
Помогите пожалуйста написать программу, которая считывает из текстового файла и записывает в новый файл только строки, содержащие двоичные...

Чтение/запись в файл - C++
Почему то попытка создать файл для записи или открыть какой либо файл для чтения оказывается неудачной, в чем может быть причина? string...

Запись и чтение в файл - C++
Вариант 1 Написать программу, которая считывает из текстового файла три предложения и выводит их в обратном порядке. Вариант 2 ...

Чтение и запись в файл - C++
#include<iostream> #include<fstream> using namespace std; void main() { setlocale(LC_ALL, "Russian"); int a, b; ...

Чтение и запись в файл - C++
Подскажите, как сделать так, чтобы информация считывалась с текстового файла, а не с консоли #include "map.h" void main(void) { ...

Чтение запись в файл - C++
Доброго времени суток. Мир нестаит на месте как и я ) недавно доделаную благодаря форумчанам программу решил сделать такой чтобы...

38
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
07.08.2014, 09:49 #16
Цитата Сообщение от Afrit Посмотреть сообщение
Мы взяли один блок
Не один, а по количеству ядер. Дальше в цикле по количеству блоков считаем хеш блока.
Вот этот цикл распараллеливаем.
1
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 11:57  [ТС] #17
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Не один, а по количеству ядер. Дальше в цикле по количеству блоков считаем хеш блока.
Вот этот цикл распараллеливаем.
Распараллелил цикл получения хэш функции.
Про количество блоков все равно не понял..
Прикрепляю солюшен. В файле crc добавил OMP. А вот с блоками что делать?
0
Вложения
Тип файла: rar Map2.rar (7.57 Мб, 3 просмотров)
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
07.08.2014, 12:25 #18
Цитата Сообщение от Afrit Посмотреть сообщение
Прикрепляю солюшен
Сорсы-то где?

Цитата Сообщение от Afrit Посмотреть сообщение
Распараллелил цикл получения хэш функции.
Ну идея была примерно такова:

Мапим часть файла, размером, равным произведению размера блока на количество ядер.
Имеем указатель на начало этого участка. Далее пишем цикл, типа:

C++
1
2
3
4
5
#pragma omp parallel for
for(int block_n=0; block_n<block_cnt;block_n++)
{
   gethash(data_start+block_n*block_size,block_size);
}
Дальше мапим следующий участок файла. И так до конца.
Или я чего-то не понимаю, или не умею объяснять.
0
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 12:32  [ТС] #19
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Сорсы-то где?
Забыл добавить. Прикрепляю.
0
Вложения
Тип файла: rar source.rar (5.9 Кб, 5 просмотров)
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 12:39  [ТС] #20
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Мапим часть файла, размером, равным произведению размера блока на количество ядер.
Имеем указатель на начало этого участка. Далее пишем цикл, типа:
Я правильно полагаю, что вот в этом коде мы мапим часть файла (не равное размеру блока на количество ядер)?
C++
1
2
3
4
5
6
7
8
9
DWORD dwBytesInBlock = sinf.dwAllocationGranularity;
 
        if (qwFileSize < sinf.dwAllocationGranularity)
 
            dwBytesInBlock = (DWORD)qwFileSize;
 
        PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, (DWORD)(qwFileOffset >> 32), // начальный байт 
            (DWORD) (qwFileOffset & 0xFFFFFFFF), // в файле
            dwBytesInBlock); // число проецируемых байтов
На этом этапе у нас есть блок. Никаких параллелей пока нет.
А потом мы добавляем параллельность при расчете хэша. Я правильно её реализовал, кстати?
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Дальше мапим следующий участок файла. И так до конца.
Или я чего-то не понимаю, или не умею объяснять.
На самом деле очень здорово объясняете. Меня смутила фраза про то, что у нас одновременно участвует несколько блоков. Это же не так верно?
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
07.08.2014, 12:55 #21
Цитата Сообщение от Afrit Посмотреть сообщение
Я правильно полагаю, что вот в этом коде мы мапим часть файла (не равное размеру блока на количество ядер)?
Ну если я правильно понимаю, то это один блок.

Цитата Сообщение от Afrit Посмотреть сообщение
А потом мы добавляем параллельность при расчете хэша. Я правильно её реализовал, кстати?
Параллелить расчет хеша одного блока не очень просто и не понимаю зачем, ИМХО параллелить проще и лучше расчет хешей нескольких блоков. Правильно или нет - не знаю, кода в архиве не нашел.

Цитата Сообщение от Afrit Посмотреть сообщение
Меня смутила фраза про то, что у нас одновременно участвует несколько блоков. Это же не так верно?
Ну судя по коду - не так, а на мой взгляд, нужно бы.
1
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 13:02  [ТС] #22
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Правильно или нет - не знаю, кода в архиве не нашел.
как так? source.rar И там тоже нет кода?
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Ну судя по коду - не так, а на мой взгляд, нужно бы.
Получается, мы должны сразу разбить проекцию на блоки? То есть взять какой-нибудь контейнер типа Pbyte. Расфасовать блоки в контейнер. и подать все эту циклу, который Вы привели?
Тогда где тут окно? Я понимаю, когда у нас один блок и окно двигается. Размер окна - размер блока. Или в окне несколько блоков? Тогда не знаю, как это реализовать...
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
07.08.2014, 13:10 #23
Цитата Сообщение от Afrit Посмотреть сообщение
Тогда где тут окно? Я понимаю, когда у нас один блок и окно двигается. Размер окна - размер блока. Или в окне несколько блоков? Тогда не знаю, как это реализовать...
Окно - отмапленная область, размер его - несколько блоков, хеши которых нужно посчитать, хеш каждого блока считается в своем потоке. Тасовать ничего никуда не надо, считаем прямо на месте.

Цитата Сообщение от Afrit Посмотреть сообщение
source.rar
А, да, сорри, вечером посмотрю, возможно начну понимать в чем проблема .

OpenMP очень удобно параллелит циклы, но только в случае, если итерации цикла независимы.
1
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 15:13  [ТС] #24
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Окно - отмапленная область, размер его - несколько блоков, хеши которых нужно посчитать, хеш каждого блока считается в своем потоке. Тасовать ничего никуда не надо, считаем прямо на месте.
Перечитал Ваши посты с самого начала и понял про окно. Количество ядер, как найти я знаю. Размер окна найти труда не составит. Нужно зарезервировать пространства для окна, верно? и про контейнер я правильно сказал?
Не могли бы Вы поподробнее описать процесс от создания проекции до хэширования блоков? Буду очень признателен, если на важных участках конструкции кода приведете.

Добавлено через 1 час 44 минуты
Создаем окно
C++
1
PVOID pbmem = VirtualAlloc(NULL, dwBytesInBlock * numCPU, MEM_RELEASE | MEM_COMMIT, PAGE_READWRITE);
Указатель на начало qwFileOffset, количество файлов в блоке dwBytesInBlock. Функция хэширования блока CRC32_function.
Я не знаю, как разбить созданное окно по блокам. У меня складывается ощущение, что это надо делать параллельно, чтобы потом передать в параллельный цикл, который Вы написали. Или нет?
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 1
07.08.2014, 19:33 #25
Народ, я нифига не понял. Объясните мне, на кой все так усложнять?
Зачем тут нужны отображаемые в память файлы?
Зачем тут нужен OpenMP?
Почему бы просто-напросто не реализовать паттерн producer/consumer?
0
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 20:35  [ТС] #26
Цитата Сообщение от ct0r Посмотреть сообщение
Почему бы просто-напросто не реализовать паттерн producer/consumer?
Как я понимаю, отправляем блоки. Выдаем хэш. А многопоточность? В чем плюс producer/consumer? Прочел статью на msdn, но пользы не увидел. Что упростит?
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 1
07.08.2014, 20:41 #27
Цитата Сообщение от Afrit Посмотреть сообщение
А многопоточность?
А что с ней не так? Несколько потоков есть.
Цитата Сообщение от Afrit Посмотреть сообщение
В чем плюс producer/consumer? Прочел статью на msdn, но пользы не увидел.
Считывание данных выполняется параллельно с их обработкой.
Цитата Сообщение от Afrit Посмотреть сообщение
Что упростит?
Реализацию упростит. Зачем там нужны отображаемые в память файлы и OpenMP, объясни?
0
Afrit
6 / 6 / 1
Регистрация: 27.08.2013
Сообщений: 128
07.08.2014, 21:02  [ТС] #28
Цитата Сообщение от ct0r Посмотреть сообщение
Реализацию упростит. Зачем там нужны отображаемые в память файлы и OpenMP, объясни?
Я не претендую Про метод услышал от Вас, про openmp от uglyPinokkio.
Пытаюсь сделать хоть как то. Можете накидать примерный план с producer/consumer? или скинуть литературу с примерчиками?
План с кусками кода лучше всего, конечно
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 1
07.08.2014, 23:57 #29
Цитата Сообщение от Afrit Посмотреть сообщение
Можете накидать примерный план с producer/consumer?
Producer - поток, читающий файл и помещающий блоки данных в потокобезопасную очередь. Consumer - поток, берущий блоки данных из потокобезопасной очереди, считающий и записывающий хеш.
Цитата Сообщение от Afrit Посмотреть сообщение
или скинуть литературу с примерчиками?
Вбей в гугле "producer consumer" или "производитель потребитель" и выбери сам то, что поймешь лучше.
Цитата Сообщение от Afrit Посмотреть сообщение
План с кусками кода лучше всего, конечно
Код простой, должен сам осилить а вообще советую использовать для этого дела библиотеку Intel TBB - это можно сказать STL параллельного программирования.
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
08.08.2014, 07:58 #30
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от ct0r Посмотреть сообщение
Народ, я нифига не понял. Объясните мне, на кой все так усложнять?
Это отмапить файл и посчитать в цикле хеши сложно?

Цитата Сообщение от Afrit Посмотреть сообщение
Я не знаю, как разбить созданное окно по блокам.
Примерно так:

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
   while (qwFileSize > 0)
   {
 
      // определяем, сколько байтов надо спроецировать 
      DWORD dwBytesInBlock = sinf.dwAllocationGranularity;
      int n_blocks = omp_get_max_threads();
      DWORD dwBytesInParallelBlocks = dwBytesInBlock*n_blocks;
      std::vector<unsigned int> crc_s;
      crc_s.resize(n_blocks,0);
      if (qwFileSize < dwBytesInParallelBlocks)
      {
         n_blocks = 1;
         if (qwFileSize < dwBytesInBlock)
         {
            dwBytesInBlock = (DWORD)qwFileSize;
         }
         dwBytesInParallelBlocks = dwBytesInBlock;
      }
 
      PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, (DWORD)(qwFileOffset >> 32), // начальный байт 
         (DWORD) (qwFileOffset & 0xFFFFFFFF), // в файле
         dwBytesInParallelBlocks); // число проецируемых байтов
 
      #pragma omp parallel for
      for(int n_block=0;n_block<n_blocks;n_block++)
      {
         crc_s[n_block] = CRC32_function(pbFile+dwBytesInBlock*n_block, dwBytesInBlock);
      }
 
      for(int n_block=0;n_block<n_blocks;n_block++)
      {
         cout<<"n_block "<<n_block<<" crc "<<crc_s[n_block]<<endl;
      }
 
      // прекращаем проецирование представления, чтобы в адресном пространстве 
      // не образовалось несколько представлений одного файла
 
      UnmapViewOfFile(pbFile);
 
      // переходим к следующей группе байтов в файле 
      qwFileOffset += dwBytesInParallelBlocks;
      qwFileSize -= dwBytesInParallelBlocks;
 
   }
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.08.2014, 07:58
Привет! Вот еще темы с ответами:

Чтение и запись в файл - C++
В общем мне нужно читать из файла таблицу и пихать её в стек, а так же этот стек запихнуть обратно в файл.Однако если просто записывать...

Чтение и запись в файл - C++
Задача такая: Есть файл data.txt, в нем хранятся фамилии, номера телефонов и года регистрации в таком виде: *fфамилия 1 *nномер 1 ...

Чтение и запись в файл - C++
Люди скиньте пожалуйста информацию по этой теме &quot;Чтение и запись в файл&quot; Очень надо

Чтение и запись в файл - C++
#include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; int main() { int S, x, i, z, k,f; ofstream f(&quot;2.txt&quot;,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
08.08.2014, 07:58
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru