Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Запись и чтение структуры данных в разделяемую память в Linux  (Прочитано 6798 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Oopss

  • Автор темы
  • Любитель
  • *
  • Сообщений: 55
    • Просмотр профиля
Здравствуйте!!!
Вот пример записи в разделяемую память в Linux'е:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>

#define SHMEM_SIZE 4096
#define SH_MESSAGE "Hello World!\n"

/*
 *
 */
int main(int argc, char** argv) {

    int shm_id;
    char * shm_buf;
    int shm_size;
    struct shmid_ds ds;

    shm_id = shmget ( 2011, SHMEM_SIZE, IPC_CREAT | IPC_EXCL | 0600 );
    if ( shm_id == -1 ) {
        fprintf ( stderr, "shmget() error\n");
        return 1;
    }

    shm_buf = ( char * ) shmat ( shm_id, NULL, 0 );
    if ( shm_buf == ( char * ) -1) {
        fprintf ( stderr, "shmat() error\n");
        return 1;
    }

    shmctl ( shm_id, IPC_STAT, &ds );
    shm_size = ds.shm_segsz;

    if ( shm_size < strlen ( SH_MESSAGE ) ){
        fprintf ( stderr, "error: segsize = %d\n", shm_size );
        return 1;
    }

    strcpy ( shm_buf, SH_MESSAGE );

    printf ( "ID: %d\n ", shm_id );
    fgetc ( stdin );
    shmdt ( shm_buf );
    shmctl( shm_id, IPC_RMID, NULL );

    return 0;

}

Вот пример для чтения данных из разделяемой памяти:
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>

#define SH_SIZE 6

/*
 *
 */
int main(int argc, char** argv) {

    int shm_id;
    key_t ipckey;
    char * shm_buf;

/*
    if ( argc < 2 ){
        fprintf ( stderr, " Too few arguments\n");
        return 1;
    }
*/

    shm_id = shmget ( 2011, 1, 0600 );

    printf ( " shm_id = %d\n", shm_id );

    if ( shm_id == -1 ) {
        printf ( "shmget error \n" );
        shmctl( shm_id, IPC_RMID, NULL );
        return 1;
    }

    shm_buf = ( char * ) shmat ( shm_id, 0, 0 );
    if ( shm_buf == ( char * ) -1 ){
        fprintf ( stderr, " shmat() error\n");
        return 1;
    }

    printf (" Message: %s\n", shm_buf );
    shmdt ( shm_buf );

    return 0;
}

Я не очень силен в С, подскажите как записать/считать в разделяемую память массив структур TrapVarBaseStat[20]:

struct TrapVarBase {
    u_char Number; long int IP; u_char Mode; u_char OnOff;
}TrapVarBaseStat[20];


Хорошо было бы чтобы массив структур TrapVarBaseStat[20] хранился именно в разделяемой памяти (этот массив записывается одним процессом а считывается другим).
Помогите пожалуйста.
Спасибо!!!
« Последнее редактирование: 31 Мая 2011, 11:52:14 от Oopss »

andrey_p

  • Гость
А собственно вопрос в чем заключается? Как записать массив (какой размер - всегда определенный или разный?) структур в память с потерей типа и потом считать в нужные переменные? Ну на malloc потренироваться для начала можно. Из самого массива сделать структуру, где первым элементом будет размер массива, а вторым - сам массив (можно, на всякий случае, и поле с sizeof структуры добавить).

Вообще разделяемая память в общем случае - это довольно большие заморочки (размер, синхронизация), что использовать надо только там, где скорость превыше всего. И "несилен в С" тут как-то не годится ИМО.

Если это реальная, а не, допустим, учебная задача, я бы для начала использовал обыкновенный текстовый формат и обыкновенный временный файл. Как все будет работать, можно было бы перейти на использование ФИФО и бинарный формат, а потом уже разделяемую память. И тестирование, тестирование и еще раз тестирование (как завещали:)).

Оффлайн Oopss

  • Автор темы
  • Любитель
  • *
  • Сообщений: 55
    • Просмотр профиля
Вопрос заключается в том как записать массив структур TrapVarBaseStat в разделяемую память? Размер массива структур постоянен. С потерей типа или без потери типа, всеравно. Лишь бы можно было считывать то что записалось =).
Спасибо!

Пользователь решил продолжить мысль 31 Мая 2011, 12:37:58:
Вот нашел запись своей структуры в разделяемую память:  http://wiki.linuxformat.ru/index.php/LXF82:Unix_API    :)
« Последнее редактирование: 31 Мая 2011, 12:37:58 от Oopss »

andrey_p

  • Гость
Ну значит проблема решена.  ;)

Оффлайн Oopss

  • Автор темы
  • Любитель
  • *
  • Сообщений: 55
    • Просмотр профиля

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Книжка: У. Стивенс - UNIX. Взаимодействие процессов
Там всё на пальцах с примерами.
Она, кстати, в списке литературы по ссылке http://wiki.linuxformat.ru/index.php/LXF82:Unix_API

Оффлайн 8vito8

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля

 я бы для начала использовал обыкновенный текстовый формат и обыкновенный временный файл. Как все будет работать, можно было бы перейти на использование ФИФО и бинарный формат, а потом уже разделяемую память. И тестирование, тестирование и еще раз тестирование (как завещали:)).


У меня сейчас обмен данными через текстовые файлы на диске в оперативной памяти. Один процесс записывает, другой читает, необходимо примерно 16 МБ в секунду. Есть ли смысл изучать разделяемую память? Увеличит ли это скорость обмена?

andrey_p

  • Гость
Конечно увеличит и сильно. Но вот насколько сильно и нужно ли - все сейчас так сильно от системы зависит, что сказать трудно. Если объемы пересылок небольшие, то данные могут кэшироваться и реальная скорость обмена может быть намного выше. 16 Мгб/сек - не туда, не сюда. Не очень медленно, конечно, но и совсем не быстро. Попробуй FIFO - это намного легче и скорость всяко тоже должна увеличиться.

ЗЫ Отправил и прочитал, что диск в памяти. В любом случае (из-за работы файловой подсистемы ядра) - FIFO будет быстрее, а общая память еще быстрее. Но диск в памяти должен в любом случае (при стандартной нагрузке) давать скорость намного большую чем 16М/с.
« Последнее редактирование: 29 Июля 2011, 09:36:47 от andrey_p »

Оффлайн 8vito8

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
диск в памяти должен в любом случае (при стандартной нагрузке) давать скорость намного большую чем 16М/с.
Наверно, у меня большая часть времени тратится на обработку этих данных (после чтения) и их последующую визуализацию - попробую разнести обработку и визуализацию в отдельные процессы. Спасибо!

 

Страница сгенерирована за 0.054 секунд. Запросов: 25.