IPC посредством отображаемой памяти, ошибка шины

Модератор: Модераторы разделов

Аватара пользователя
kosmonaFFFt
Сообщения: 183
ОС: win 7, Kubuntu 10.10

IPC посредством отображаемой памяти, ошибка шины

Сообщение kosmonaFFFt »

Доброго времени суток.

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

Пытаюсь сделать это так:
сервер - создает отображение файла и ждет клиента.

Код:

#include <iostream> #include <string> #include <fcntl.h> #include <sys/mman.h> #include <errno.h> int main(int argc, char * * argv) { std::cout << "Mapped file name = [./../mf]" << std::endl; std::string mapped_file_name; std::cin >> mapped_file_name; //Try open file. int mapped_file_handle = open(mapped_file_name.c_str(), O_RDWR); if (mapped_file_handle < 0) { std::cout << "ERROR!!! File not opened!!!" << std::endl; return 1; } //Try map file. void * file_map = mmap(0, 10 * getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, mapped_file_handle, 0); if (file_map == MAP_FAILED) { std::cout << "ERROR!!! File not mapped!!!" << std::endl << "Error code = " << errno << std::endl; return 1; } close(mapped_file_handle); memset(file_map, 0, 10 * getpagesize()); //Wait client. int * int_file_map = (int *)file_map; while (*int_file_map == 0) { sleep(5); } sleep(5); //Read matrix size. int matrix_size = *int_file_map; std::cout << matrix_size; //Alloc memory for matrixs. float * * first_matrix = new float * [matrix_size]; float * * second_matrix = new float * [matrix_size]; for (int index = 0; index < matrix_size; ++index) { first_matrix[index] = new float [matrix_size]; second_matrix[index] = new float [matrix_size]; } //Unmap file. munmap(file_map, 10 * getpagesize()); //Free memory. for (int index = 0; index < matrix_size; ++index) { delete [] first_matrix[index]; delete [] second_matrix[index]; } delete [] first_matrix; delete [] second_matrix; return 0; }


клиент - запускается после сервера, отображает файл на память и пишет туда данные:

Код:

#include <iostream> #include <string> #include <sys/mman.h> #include <fcntl.h> int main(int argc, char * * argv) { std::cout << "Mapped file name = [./../mf]" << std::endl; std::string mapped_file_name; std::cin >> mapped_file_name; //Try open file. int mapped_file_handle = open(mapped_file_name.c_str(), O_RDWR | O_TRUNC); if (mapped_file_handle < 0) { std::cout << "ERROR!!! File not opened!!!" << std::endl; return 1; } //Try map file. void * file_map = mmap(NULL, 10 * getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, mapped_file_handle, 0); if (file_map == MAP_FAILED) { std::cout << "ERROR!!! File not mapped!!!" << std::endl; return 1; } close(mapped_file_handle); int matrix_size = 0; std::cout << "Matrix size = "; std::cin >> matrix_size; //Alloc memory for matrixs. float * * first_matrix = new float * [matrix_size]; float * * second_matrix = new float * [matrix_size]; for (int index = 0; index < matrix_size; ++index) { first_matrix[index] = new float [matrix_size]; second_matrix[index] = new float [matrix_size]; } //Read matrixs. std::cout << "Enter first matrix:" << std::endl; for (int line_number = 0; line_number < matrix_size; ++line_number) { for (int column_number = 0; column_number < matrix_size; ++column_number) { std::cin >> first_matrix[line_number][column_number]; } } std::cout << "Enter second matrix:" << std::endl; for (int line_number = 0; line_number < matrix_size; ++line_number) { for (int column_number = 0; column_number < matrix_size; ++column_number) { std::cin >> second_matrix[line_number][column_number]; } } //Write matrix to file_map. int * int_file_map = (int *)file_map; *int_file_map = matrix_size; ++int_file_map; float * float_file_map = (float *)int_file_map; for (int line_number = 0; line_number < matrix_size; ++line_number) { for (int column_number = 0; column_number < matrix_size; ++column_number) { *float_file_map = first_matrix[line_number][column_number]; ++float_file_map; } } for (int line_number = 0; line_number < matrix_size; ++line_number) { for (int column_number = 0; column_number < matrix_size; ++column_number) { *float_file_map = second_matrix[line_number][column_number]; ++float_file_map; } } //Unmap file. munmap(file_map, 10 * getpagesize()); //Free memory. for (int index = 0; index < matrix_size; ++index) { delete [] first_matrix[index]; delete [] second_matrix[index]; } delete [] first_matrix; delete [] second_matrix; }


(жирным выделил запись в память)

После запуска сервера он спокойно себе висит и ждет записи в отображаемый файл,
после заапуска клиента и сервер и клиет завершаются с сообщением "Ошибка шины"

Соответственно вопрос:
Что я делаю не так и как надо?

Заранее спасибо.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: IPC посредством отображаемой памяти, ошибка шины

Сообщение Rootlexx »

kosmonaFFFt
А сервер завершается сразу после запуска клиента или через некоторое время (пару секунд)?
Есть следующее соображение: у вас открытие файла в клиенте происходит так:

Код: Выделить всё

int mapped_file_handle = open(mapped_file_name.c_str(), O_RDWR | O_TRUNC);
— то есть при открытии файла его размер урезается до нуля. При этом клиент упадёт при попытке записи в файл, а сервер — при попытке по указателю прочесть 4 байта (int) из пустого файла.
Я бы посоветовал проверить, какие сигналы посылаются приложению («ошибка шины» — SIGBUS, означающий неверный доступ к памяти?), проверить, вообще на каком шаге происходит аварийный выход из программы, и какое значение при этом имеет errno.
Спасибо сказали:
Аватара пользователя
kosmonaFFFt
Сообщения: 183
ОС: win 7, Kubuntu 10.10

Re: IPC посредством отображаемой памяти, ошибка шины

Сообщение kosmonaFFFt »

*Ушел биться головой ап стену, ибо не заметил такой простейшей ошибки*
Спасибо огромное. Действительно косяк был из за обрезания файла при открытии,
я про него совсем забыл.
Спасибо сказали: