생성 속성은 기존 큐를 재설정하지 않습니다
mq_open의 O_CREAT는 큐가 없을 때 생성합니다. 기존 큐를 열면 mode와 생성용 attr로 권한·용량이 다시 설정되지 않습니다. 새 큐만 허용하려면 O_CREAT와 O_EXCL을 함께 사용하고 EEXIST를 처리합니다. 새 큐의 권한에는 umask가 적용됩니다.
열기에 성공한 뒤 mq_getattr로 mq_maxmsg, mq_msgsize, mq_curmsgs를 읽습니다. 수신자는 자신이 요청했던 크기가 아니라 실제 열린 큐의 mq_msgsize에 맞춰 버퍼를 준비해야 합니다. 이름은 같아도 이전 실행이 남긴 큐일 수 있습니다.
메시지 경계와 우선순위를 보존합니다
mq_receive는 가장 높은 우선순위의 메시지 중 가장 오래된 것을 꺼냅니다. 모든 메시지가 단순 FIFO로 섞이는 것이 아니라 같은 우선순위 안에서 순서가 유지됩니다. 높은 우선순위만 계속 들어오는 상황은 낮은 우선순위 작업의 지연을 만들 수 있으므로, 우선순위 정책과 부하를 함께 설계합니다.
수신 버퍼는 다음 메시지의 실제 길이만큼이 아니라 큐의 최대 메시지 크기인 mq_msgsize 이상이어야 합니다. 작으면 EMSGSIZE입니다. 반환된 바이트 수로 데이터를 해석하며, 임의의 메시지가 NUL로 끝나는 문자열이라고 가정하지 않습니다.
가득 찬 큐와 빈 큐의 대기를 구분합니다
기본 blocking 동작에서 송신은 큐가 가득 차면, 수신은 큐가 비면 기다립니다. O_NONBLOCK이면 각각 EAGAIN으로 돌아옵니다. 재시도 여부와 버리기·재전송·종료 정책은 애플리케이션에서 정해야 합니다.
mq_timedsend와 mq_timedreceive는 CLOCK_REALTIME 기준의 절대 시각을 받습니다. 상대 대기시간을 그대로 넣지 않습니다. EINTR 후 재시도할 때 기한을 매번 새로 늘리지 않도록 하고, ETIMEDOUT을 실제로 처리합니다. 시스템 시각의 변경도 절대 기한에 영향을 줄 수 있습니다.
닫기와 이름 제거는 다른 일입니다
mq_close는 현재 descriptor를 닫습니다. mq_unlink는 이름을 즉시 제거하지만 이미 열린 descriptor가 있으면 큐 객체는 마지막 descriptor가 닫힐 때까지 남습니다. 종료할 때 어느 프로세스가 이름을 제거할지 합의하지 않으면, 재시작할 때 오래된 큐를 다시 열 수 있습니다.
mq_open: 이름으로 큐 참조 획득
mq_unlink: 이후의 이름 검색에서 제거
마지막 mq_close: 남아 있던 큐 객체 소멸
Linux의 관측값을 정확히 읽습니다
/dev/mqueue는 mqueue 파일시스템이 그 위치에 마운트된 경우의 관측 경로입니다. 컨테이너에서는 IPC namespace도 확인합니다. QSIZE는 메시지 데이터의 바이트 수이며 mq_curmsgs처럼 메시지 개수가 아닙니다. NOTIFY는 알림 방식 번호이지 단순한 켜짐·꺼짐 값이 아닙니다.
생성 실패에서는 /proc/sys/fs/mqueue의 큐 수·크기 제한과 실제 UID에 적용되는 RLIMIT_MSGQUEUE를 함께 확인합니다. 이 글은 API와 문서의 정적 대조이며 Linux에서 예시를 빌드하거나 실행한 결과가 아닙니다.