2015-11-30 51 views
10

Aktualnie używam kolejek komunikatów systemu V w systemie Mac OSX i mam problemy z ustawieniem rozmiaru kolejki na wartość większą niż 2048 bajtów. Oto kompilacji stanie przykład test.c:Ustawianie rozmiaru kolejki komunikatów systemu V w systemie Mac OSX

#include <stdio.h> 
#include <sys/msg.h> 
#include <stdlib.h> 

int main() { 
    // get a message queue id 
    int id = msgget(IPC_PRIVATE,IPC_CREAT|0600); 
    if (-1 == id) 
     exit(1); 

    // get message queue data structure 
    struct msqid_ds buf; 
    if (-1 == msgctl(id, IPC_STAT, &buf)) 
     exit(1); 
    printf("size is %lu bytes\n", buf.msg_qbytes); 

    // set new buffer size 
    buf.msg_qbytes = 2750; 
    printf("setting size to %lu bytes\n", buf.msg_qbytes); 
    if (-1 == msgctl(id, IPC_SET, &buf)) 
     exit(1); 

    // check updated message queue data structure 
    if (-1 == msgctl(id, IPC_STAT, &buf)) 
     exit(1); 
    printf("size is %lu bytes\n", buf.msg_qbytes); 
} 

skompilować z:

clang -Wall -pedantic -o test test.c 

i biegać z:

sudo ./test 

Uwaga: Musisz uruchomić powyższy kod z sudo aby upewnić się, że wywołania msgcntl zakończą się pomyślnie.

Wyjście tego programu fragmencie brzmi:

size is 2048 bytes 
setting size to 2750 bytes 
size is 2048 bytes 

Dlaczego nie wielkość kolejka zaczyna się zmieniło?

EDIT: Wyjście ipcs -Q Wystawy:

IPC status from <running system> as of Tue Dec 1 10:06:39 PST 2015 
msginfo: 
    msgmax: 16384 (max characters in a message) 
    msgmni:  40 (# of message queues) 
    msgmnb: 2048 (max characters in a message queue) 
    msgtql:  40 (max # of messages in system) 
    msgssz:  8 (size of a message segment) 
    msgseg: 2048 (# of message segments in system) 

Czy msgmnb być wykonane większe, albo ja zatrzymany?

+0

Spróbuj uruchomić 'ipcs-Q', aby sprawdzić, czy istnieje maksymalny rozmiar. –

+0

@MarkSetchell - zaktualizowałem pytanie o wynik działania 'ipcs-Q'. – dinkelk

+0

Nigdy nie próbowałem tego na OSX, i nie wiem, czy to działa lub może powodować problemy, ale myślę, że zrobiłbyś coś takiego jak 'sysctl -w kernel.msgmnb = 2000000' –

Odpowiedz

5

Wygląda na to, że OS X nie pozwala zwiększyć rozmiaru kolejki komunikatów. Implementacja systemu V jest stara i nie udokumentowana w ogóle. Znalazłem również dziwne, że brakuje definicji MSGMNB, MSGMAX w message.h, podczas gdy można go znaleźć w Linuxie i innych implementacjach Uniksa.

Uważam też to:

OS X jest najgorszy z partii. Każda kolejka jest ograniczona do 2048 bajtów i OS X po cichu ignoruje próby jej zwiększenia (podobnie jak FreeBSD). Aby dodać obrażenie do obrażeń, wydaje się, że nie ma możliwości zwiększenia tego limitu ograniczenia rekompilacji jądra. Zgaduję, że na podstawie limitów kolejki wiadomości Darwin w oparciu o .(http://semanchuk.com/philip/sysv_ipc/)

Dokument został zaktualizowany września 2014 i potwierdza wpis na liście jabłoni korespondencji:

http://lists.apple.com/archives/unix-porting/2008/Jan/msg00033.html

podkreślił @Mark Setchell w komentarzu.

Również niedawne wdrożenie Ruby Wrapper nie jest obsługiwane na OS X jako autor stwierdza, że:

Komunikaty są obsługiwane przez jądro komputera. Nie wszystkie jądra mają obsługę kolejek komunikatów POSIX, szczególnie przykładem jest Darwin (OS X). Darwin implementuje starszy system IPC API. (https://github.com/Sirupsen/posix-mqueue)

W internecie istnieją inne źródła (głównie stare), które wskazują, że nie ma sposobu innego niż kompilacji jądra do zwiększenia limitów kolejki.

UPDATE: pozycja Apple ma zniechęcać do korzystania z System V IPC here:

jakiś system V prymitywy są obsługiwane, ale ich stosowanie jest zalecane za odpowiedniki POSIX.

Side sugestia, dodać: msgctl(id, IPC_RMID, NULL); na końcu kodu testowego, ktoś (tak jak ja, wzdychać!) Mógł zapomnieć, że każda kolejka musi być zamknięty.

+0

Niestety nie ma odpowiednika POSIX dla kolejek komunikatów systemu V na Macu, ponieważ kolejek Posix nie są obsługiwane w ogóle – dinkelk

+0

@dinkelk Tak, ale dziwnie, jak widać, to jest zgłaszane w rozwoju strona robocza –

-1

strona man dla msgctl()

polu kod zmienia to numer prąd bajtów w kolejce, a nie maksymalna liczba bajtów w kolejce.

Zaleca się, aby spojrzeć na: msglen_t msg_qbytes, która jest maksymalną liczbą bajtów dozwoloną w kolejce.

+0

Jeśli spojrzysz na moje kod, w rzeczywistości zmienia 'msg_qbytes'. – dinkelk

1

Mam problemy ze znalezieniem Mac specyficzną dokumentację, ale POSIX says że gdy kolejka komunikatów jest tworzony poprzez msgget(), jego „msg_qbytes ustala się równe granicy systemu.” Strona podręcznika BSD dla msgget() mówi to samo i jest to najbliższy krewny OS X. O ile warto, strony man Linux wydają się powszechnie zgadzać.

To całkiem nieźle wskazuje na to, że jeśli początkowy rozmiar kolejki nie jest wystarczająco duży, zostaniesz podciągnięty. Możesz (może) zmniejszyć to, ale nie możesz wyrosnąć poza jego początkową wartość.