0 / 0 / 0
Регистрация: 18.12.2015
Сообщений: 23
1

Передача информации между процессами через MappingFile

29.10.2017, 20:03. Показов 4486. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача такая, реализовать программу копирующую файл, где в одном процессе происходит чтение, а во втором запись, для передачи данных между процессами решил использовать MappingFile, но не могу понять как записать в него в одном процессе, а потом прочитать в другом? Или может есть лучшее идеи передачи информации между процессами?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2017, 20:03
Ответы с готовыми решениями:

MappingFile передача информацию между процессами
Не могу осуществить реализацию, где в одном процессе создаем mapping и записываем в него массив, а...

Передача строки символов между процессами с использованием именованных каналов
Нашел пример по теме, но как нужно запускать эти части и произвести передачу данных от одного...

Передача классов между процессами через WCF
Есть ли способ передать класс из одного процесса в другой? То есть первый процесс пользуется...

Передача сообщений между процессами
Python 3.4. GUI - WxPython Имеется локальный сервер на Flask. На сервере крутится страничка,...

15
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
29.10.2017, 21:45 2
Отображение файла на память это не лучший способ обмена данными между процессами. Лучше использовать каналы (pipes) - они позволяют обмениваться в том числе по сети, хотя и ограниченно. Другая проблема с каналами, что мне так и не удалось сделать их неблокирующими (чтобы читающая программа не зависала если канал пуст). Может, вам повезет больше.
Еще один способ - разделяемая память, но с этим я дела не имел.
Другое дело что если нужен результат а не процесс, есть стандартные способы, не обязательно изобретать велосипед.
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
29.10.2017, 23:09 3
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Другая проблема с каналами, что мне так и не удалось сделать их неблокирующими (чтобы читающая программа не зависала если канал пуст).
Не пробывал в отдельном потоке пускать чтения, а затем уведомлять основной?

Цитата Сообщение от poteytus Посмотреть сообщение
Задача такая, реализовать программу копирующую файл, где в одном процессе происходит чтение, а во втором запись, для передачи данных между процессами решил использовать MappingFile, но не могу понять как записать в него в одном процессе, а потом прочитать в другом?
Если вообще влоб, то копируем файл в виртуальную память первого процесса.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <iomanip>
int main()
{
    std::ifstream file("something", std::ios::binary | std::ios::ate);
    std::vector<char> fileInMemory(file.tellg());
    file.seekg(0);
    
 
    std::copy(
        std::istreambuf_iterator<char>(file),
        std::istreambuf_iterator<char>(),
        fileInMemory.begin());
 
    std::cout << std::showbase << std::internal << std::setfill('0');
    std::cout << "File at " << std::hex << std::setw(10) <<(unsigned int)fileInMemory.data() << "\tSize: " << std::dec << fileInMemory.size() << std::endl;
    std::cin.get();
    return 0;
}

Магическим образом передаем адрес памяти и размер, который необходимо прочитать, другому процессу и читаем его ( если винда, то OpenProccess->ReadProcessMemory).
А вообще хотелось бы увидеть нормальную реализацию MappingFile (без буста).
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 00:50 4
Цитата Сообщение от lArtl Посмотреть сообщение
Не пробывал в отдельном потоке пускать чтения, а затем уведомлять основной?
Так обмен и должен был быть между отдельными потоками. Чтобы передавать данные потоком, а не мьютексами. Да и потом, неужели нет нормального способа?
Цитата Сообщение от lArtl Посмотреть сообщение
Если вообще влоб, то копируем файл в виртуальную память первого процесса.
А хватит памяти? Мы же не знаем размер файла.
Цитата Сообщение от lArtl Посмотреть сообщение
А вообще хотелось бы увидеть нормальную реализацию MappingFile (без буста).
Могу выложить свою реализацию. Надо?
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
30.10.2017, 02:01 5
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А хватит памяти? Мы же не знаем размер файла.
Размер файла мы знаем. Да и не думаю, что планируется кидаться файлами больше гигабайта.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Могу выложить свою реализацию. Надо?
Я б для себя посмотрел бы.

Добавлено через 59 секунд
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Так обмен и должен был быть между отдельными потоками. Чтобы передавать данные потоком, а не мьютексами. Да и потом, неужели нет нормального способа?
Чет мне кажется, что пайпы не про это)
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 09:14 6
Цитата Сообщение от lArtl Посмотреть сообщение
не думаю, что планируется кидаться файлами больше гигабайта.
Откуда нам знать? Если есть возможность делать универсально, лучше так и сделать. Если решать именно ту задачу, которую описал ТС (один процесс читает файл, передает данные второму, тот пишет), можно использовать каналы, разделяемую память с семафорами, может даже сеть. При чем на счет каналов можно сделать даже на стандартных программах: cat file | tee file_cp (не знаю как именно это в DOS делается).
Цитата Сообщение от lArtl Посмотреть сообщение
Чет мне кажется, что пайпы не про это)
А для чего тогда?
Цитата Сообщение от lArtl Посмотреть сообщение
Я б для себя посмотрел бы.
https://github.com/COKPOWEHEU/memfile/tree/master
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include "include/memfile.h"
 
int main(){
  struct memfile_t pf;
  char res = memfile_create( "any_file.txt", MEMFILE_READWRITE | MEMFILE_REWRITE, 100, &pf);
//аргументы: имя_файла ; флаги и права ; размер (в байтах) ; результат
  if( res != MEMFILE_OK ){printf("Can not create file\n"); return 1;}
  char *data = pf.data; //буфер объявлен как void*, приведем просто к массиву char'ов (наверное, потом исправлю)
  
  sprintf(pf.data, "text     \n"); //демонстрация работы
  data[4] = '!';
  
  memfile_close(&pf); //не забываем закрыть
}
0
Maniac
Эксперт С++
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
30.10.2017, 14:08 7
Дауж... загнули вы... (куча болтовни, а толку мало)


Задача такая, реализовать программу копирующую файл, где в одном процессе происходит чтение, а во втором запись, для передачи данных между процессами решил использовать MappingFile, но не могу понять как записать в него в одном процессе, а потом прочитать в другом? Или может есть лучшее идеи передачи информации между процессами?
Creating Named Shared Memory
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 14:24 8
Это-то еще в первом ответе было предложено. Но мы не знаем задачу ТСа. Вдруг ему надо именно через отображение файла на память.
0
Maniac
Эксперт С++
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
30.10.2017, 14:40 9
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Отображение файла на память это не лучший способ обмена данными между процессами.
Чем это плохо, если решает задачу?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Другая проблема с каналами, что мне так и не удалось сделать их неблокирующими (чтобы читающая программа не зависала если канал пуст). Может, вам повезет больше.
Грубо говоря
со стороны клиента
C
1
2
3
4
5
6
7
8
9
10
11
12
    bool send(void *buffer, unsigned size) {
 
        if (nullptr == buffer || size == 0 || size > MAX_BUFFER_SIZE)
            return false;
 
        DWORD BytesRead;
        int lpPipeBufferRead;
 
            return CallNamedPipeW(_pipe_name.c_str(), buffer, size,
                &lpPipeBufferRead, sizeof(int),
                &BytesRead, NMPWAIT_NOWAIT);
    }
со стороны сервера
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
45
46
47
48
49
50
51
52
    
 
        _hNamedPipe = CreateNamedPipeW(
            _pipe_name.c_str(),
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            MAX_BUFFER_SIZE, MAX_BUFFER_SIZE, 5000, NULL);
......
 
bool accept() {
 
        DWORD cbRead = 0;
 
        while (_accept)
        {
            if (ConnectNamedPipe(_hNamedPipe, NULL) == NULL) {
                break;
            }
 
 
            if (ReadFile(_hNamedPipe, _lpPipeBufferRead, MAX_BUFFER_SIZE, &cbRead, NULL))
            {
                recive(_lpPipeBufferRead, cbRead, MAX_BUFFER_SIZE);
            }
 
            DisconnectNamedPipe(_hNamedPipe);
        }
 
        return true;
    }
 
    virtual void recive(void* buffer, unsigned buffer_size, unsigned max_size) = 0;
 
    void send(void* buffer, unsigned buffer_size) {
        DWORD cbRead = 0;
        int _PipeBufferWrite = 0;
        if (buffer == 0 || buffer_size == 0 || buffer_size > MAX_BUFFER_SIZE)
            WriteFile(_hNamedPipe, &_PipeBufferWrite, sizeof(int), &cbRead, NULL);
        else
            WriteFile(_hNamedPipe, buffer, buffer_size, &cbRead, NULL);
    }
....
 
    void recive(void* buffer, unsigned buffer_size, unsigned max_size) {
        message_data *buff = (message_data*)buffer;
 
        _mut_detector->read_data(buff);
 
        //!необходимо хоть что то отправить обратно... плохая реализация..
        this->send(0, 0);
    }
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 15:50 10
Цитата Сообщение от ISergey Посмотреть сообщение
Чем это плохо, если решает задачу?
Это приводит к лишним дисковым операциям (мы же записываем в отмапленный файл не результат, а передаваемые куски). То есть потеря производительности. Плюс надо каким-то образом регулировать обмен чтобы не было одновременной записи и чтения одной и той же области.
Я не говорю, что отображение памяти на файл нельзя использовать для обмена, но это неэффективный и сложный способ.
Цитата Сообщение от ISergey Посмотреть сообщение
Грубо говоря
А можно полный код? Использование простых WriteFile / ReadFile без callback'ов и событий нужного эффекта вообще не давало. К тому же у вас канал создается не байтовый и с флагом PIPE_WAIT.
Пока что я не представляю как дополнить этот код до рабочего состояния.
1
0 / 0 / 0
Регистрация: 18.12.2015
Сообщений: 23
30.10.2017, 18:33  [ТС] 11
Был бы очень благодарен

Добавлено через 36 минут
COKPOWEHEU, если не затруднит, не могли бы выложить реализацию, где в одном процессе создаём mapping и записываем в него к примеру массив, а в другом процессе открываем mapping и читаем из него массив
0
Эксперт .NET
12569 / 8750 / 1311
Регистрация: 21.01.2016
Сообщений: 32,817
30.10.2017, 18:54 12
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Это приводит к лишним дисковым операциям (мы же записываем в отмапленный файл не результат, а передаваемые куски).
Серьёзно чтоли? А мне раньше, по наивности, казалось, что "отмапленный" файл становится общим куском адресного пространства двух процессов, и диск тут вообще никаким боком. Но вам, видимо, виднее)
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 19:33 13
Отображение файла на память это именно отображение файла (области жесткого диска) на ОЗУ. То есть работа с ОЗУ одновременно перезаписывает файл. Насколько мне известно, этот способ обычно применяется для быстрого чтения / записи файла на диск, для быстрого произвольного доступа, но не для совместной работы. Более того, один и тот же файл может отображаться на несколько непересекающихся областей ОЗУ одновременно. Собственно, я не уверен что все системы правильно понимают одновременную работу разных программ с одним и тем же файлом.
Цитата Сообщение от poteytus Посмотреть сообщение
COKPOWEHEU, если не затруднит, не могли бы выложить реализацию, где в одном процессе создаём mapping и записываем в него к примеру массив, а в другом процессе открываем mapping и читаем из него массив
Разные программы писать было лень, вместо этого макросами выделил линуксовую версию для создания файла и записи в него, а виндовую - для чтения. Проверка (виндовая версия - в wine) показала работоспособность. Разумеется, там могут найтись баги - буду благодарен если найдете и поможете исправить.
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
#include <stdio.h>
#include <unistd.h>
#include "include/memfile.h"
 
int main(){
  struct memfile_t pf;
#ifdef linux
  char res = memfile_create( "any_file.txt", MEMFILE_READWRITE | MEMFILE_REWRITE, 100, &pf);
#else
  int val;
  char res = memfile_create( "any_file.txt", MEMFILE_READ, 100, &pf);
#endif
  if( res != MEMFILE_OK ){printf("Can not create file\n"); return 1;}
  
  for(int i=0; i<1000;i++){
#ifdef linux
    sprintf(pf.data, "%i ", i);
    printf("%i / %i\n", i, 1000);
#else
    sscanf(pf.data, "%i", &val);
    printf("%i / %i = %i\n", i, 1000,  val);
#endif
    usleep(10000);
  }
  
  memfile_close(&pf);
}
0
Эксперт .NET
12569 / 8750 / 1311
Регистрация: 21.01.2016
Сообщений: 32,817
30.10.2017, 20:03 14
COKPOWEHEU, посмотрите ссылку в посте №7. Там идёт речь о mapped file без создания самого файла. Так называемая Shared Memory. Т.е. одно дело отображение в память реального файла и другое дело - IPC посредствам того же механизма, но без физического файла.
0
4026 / 2572 / 430
Регистрация: 09.09.2017
Сообщений: 11,490
30.10.2017, 23:00 15
Usaga, не путайте эти два механизма. Отображение файла на память нужно в первую очередь для работы с файлами. А разделяемая память или каналы, хоть и могут выглядеть как файлы, не служат для постоянного хранения информации.
0
131 / 116 / 25
Регистрация: 03.05.2017
Сообщений: 336
Записей в блоге: 1
03.11.2017, 20:19 16
Старaясь попасть в тему, не открывая новую тему, спрошу на смежную тему…
А можно ли вообще, находясь под чужой прикладной средой и имея в распоряжении указатель, переоформить его в FileMapping?
Поясню: Написал под VirtualDub свой фильтр, который организует задержку захватываемого потока видео ровно на 1 кадр. При загрузке плагина с моим фильтром он открывает на диске bmp-файл общего доступа со всеми заголовками. Когда с веб-камеры приходит очередной кадр, мой код пиксел за пикселом читает тот bmp-файл и отправляет всё на выход (экран/DivX-компрессор), а пиксели нового кадра помещает в bmp-файл. Т.е. bmp-файл является промежуточным звеном между источником (веб-камеры) и приёмником (записываемый avi-файл). И другая программа, специально написанная под эту цель, успевает в bmp-файл вставить свои трюки (тайм-код, OpenGL-анимацию и логотипы). Всё работает, но жрёт ресурсы - от 5% до 25% процессора…

Могу ли я не создавать промежуточный bmp-файл, а получив указатели входного кадра и кадра для моего результата оформить как два отдельных файла, чтобы избежать промежуточное копирование и сторонней своей программой напрямую работать с буферами как файлами?
Пытался я подставлять указатели в CreateFileMapping/CreateDIBSection и т.д. Возвращают они ошибку доступа. Можно ли подставить готовый указатель памяти под проекцию файла?

Спасибо!
0
03.11.2017, 20:19
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.11.2017, 20:19
Помогаю со студенческими работами здесь

Передача handle между процессами
Есть 1й процесс который создает файл и записывает в него информацию из Edit, после чего создает 2й...

Передача данных между процессами (pipe)
Всем доброго времени суток. Обращаюсь к вам с вопросиком. Передо мной стоит задача написать код,...

Передача сообщений между процессами и потоками
Здравствуйте, помогите, пожалуйста, с задачей по Операционным системам: Создать процесс с двумя...

Передача данных между потоками/процессами
Ребят, у вас тут поактивнее раздел. В соседней ветке .NET я не нашел решения, может...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

Новые блоги и статьи
В чем отличие между INNER JOIN и OUTER JOIN
bytestream 22.01.2025
В современных базах данных информация часто распределена между множеством взаимосвязанных таблиц, что делает операции объединения JOIN неотъемлемой частью работы с SQL. Эти операции позволяют. . .
Как сделать первую букву заглавной в JavaScript
bytestream 22.01.2025
JavaScript предоставляет разработчикам множество инструментов для эффективной работы с текстовыми данными. Одной из часто встречающихся задач при обработке строк является преобразование первой буквы. . .
Что такое Big O нотация и алгоритмическая сложность
bytestream 22.01.2025
Введение в алгоритмическую сложность В мире разработки программного обеспечения эффективность алгоритмов играет crucial роль в создании качественных приложений. Алгоритмическая сложность. . .
Как решать конфликты слияния (merge) в Git
bytestream 22.01.2025
Конфликты слияния в системе контроля версий Git возникают в ситуациях, когда две или более ветки разработки содержат несовместимые изменения в одних и тех же участках кода. Эти конфликты представляют. . .
Как использовать регулярные выражения
bytestream 22.01.2025
Регулярные выражения представляют собой мощный инструмент для работы с текстовыми данными, который позволяет осуществлять поиск, проверку и манипуляцию строками на основе определенных шаблонов. Этот. . .
Как выйти из Vim
bytestream 22.01.2025
Vim (Vi IMproved) представляет собой один из самых влиятельных текстовых редакторов в истории компьютерной индустрии, эволюционировавший из своего предшественника Vi, созданного Биллом Джоем в 1976. . .
NoSQL базы данных: что это такое и какие существуют
bytestream 22.01.2025
В современную эпоху цифровой трансформации объемы данных растут экспоненциально, создавая новые вызовы для традиционных систем управления базами данных. NoSQL (Not Only SQL) представляет собой. . .
Обновление исследования от команды MCM (январь 2025 г.)
Programma_Boinc 22.01.2025
Обновление исследования от команды MCM (январь 2025 г. ) Мы продолжаем изучать молекулярные сигнатуры, связанные с раком легких, с текущим фокусом на GCM1, факторе транскрипции, участвующем в. . .
Как работать с Kafka в Go (Golang)
bytestream 22.01.2025
Apache Kafka представляет собой распределенную платформу потоковой передачи данных, которая произвела революцию в области обработки событий и интеграции микросервисов. Эта система, изначально. . .
Как использовать RabbitMQ в Go (Golang)
bytestream 22.01.2025
RabbitMQ представляет собой надежный и широко используемый брокер сообщений, который играет ключевую роль в построении современных распределенных систем и микросервисной архитектуры. В основе работы. . .
Как преобразовать список списков в простой список в Python
bytestream 22.01.2025
При работе с Python разработчики часто сталкиваются с необходимостью обработки сложных структур данных, среди которых особое место занимают вложенные списки. Эти структуры представляют собой списки,. . .
Что такое GUID / UUID и как их создать
bytestream 22.01.2025
В мире разработки программного обеспечения существует постоянная потребность в уникальной идентификации объектов, записей и ресурсов. Эта задача становится особенно актуальной в распределенных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru