2015-12-17 1 views
3

Я пишу программу, где мне нужно передать фрагмент массива между процессами, используя очередь сообщений (не использовать общую память для этого ...) , Этот фрагмент массива может иметь разную длину, поэтому мне интересно, как лучше всего это сделать - могу ли я указать размер сообщения во время выполнения? Я знаю, что я могу передать структуру, как это через очереди:Очередь сообщений IPC System V - отправка части массива

struct msg { 
    long type; 
    char data[N]; 
}; 

где N определяется во время компиляции, и AFAIK, я не могу сделать что-то вроде этого:

struct msg { 
    long type; 
    char *data; 
}; 

потому, что содержание указатель не будет скопирован, только его значение ...

Итак, каков наилучший способ решить эту проблему? Какой N выбрать, чтобы он работал эффективно? отправляет char data[1] ok? Я беспокоюсь, что если несколько процессов запросят большую таблицу, это создаст узкое место и не будет эффективным. Действительно ли мои заботы действительны?

ответ

2

Выделяют структуру сообщения и отправить сообщение, как это:

int sendMessage(int msqid, int flags, long type, const char *data, size_t data_size) 
{ 
    struct msgbuf *msg; 
    size_t msg_size = sizeof(msg->mtype) + data_size; 
    msg = malloc(msg_size); 
    msg->mtype = type; 
    memcpy(msg->mtext, data, data_size); 
    int rc = msgsnd(msqid, msg, msg_size, flags); 
    free(msg); 
    return(rc); 
} 

Посмотреть страницу человека для msgsnd/msgrcv на http://man7.org/linux/man-pages/man2/msgop.2.html

2

Определить максимальный размер массива, скажем, это 1024.

#define MAX_SIZE 1024 

Объявить свой-структуру, как это:

struct msg { 
    long type; 
    char data[MAX_SIZE]; 
}; 

При отправке отправить только N байт содержимого.

struct msg m; 
// fill the data with N bytes 
msgsnd(msqid, &m, N, msgflg); 

Для заполнения данных вы можете использовать, например. memcpy функция.

memcpy(msg.data, your_array + start_index_of_the_slice, N); 

При получении укажите максимальный размер, т. Е. MAX_SIZE. Проверьте, сколько байтов было действительно получено, проверяя возвращаемое значение msgrcv.

struct msg m; 
N = msgrcv(msqid, &m, MAX_SIZE, msgtyp, msgflg); 
// use the first N data bytes