[태그:] message queue

  • message queue, unix network programming 75p ~ 90p

    fifo는 먼저 들어온 순서로 동작하지만, message queue는 빠른 우선순위로 동작한다.

    signal handler를 정의하여 사용할 수도 있다. message noty는 queue가 비어있을 경우 한번 동작한다. queue가 차 있다면 signal을 무시한다. 한 번 사용하면 다시 시그널을 등록해야 한다.

    pi@raspberrypi:~/Project/cCode/IPC $ cat mesquereceive.c 
    //message que header
    #include <unistd.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    #include <signal.h>
    #define MAX_SIZE 100
    
    //signal 처리하기 위한 hanlder
    static void sig_usr1(int mysig);
    
    struct sigevent sigev;
    //signal hanlder로 사용하려고 global로 등록.
    mqd_t	mqd;
    struct mq_attr attr;
    int priorecv;
    char buff[100];
    
    int main(){
    	int		c, flags;
    	char const *quename="/tmp_message";
    	char messageptr[50]= "this is a test.";
    	//메세지 큐 초기화
    	attr.mq_flags = 0;
        attr.mq_maxmsg = 10;
        attr.mq_msgsize = MAX_SIZE;
        attr.mq_curmsgs = 0;
    
    
    	//message를 넣기전에 mq_notify 정의
    	signal(SIGUSR1, sig_usr1);
    	sigev.sigev_notify = SIGEV_SIGNAL;
    	sigev.sigev_signo = SIGUSR1;
    	mq_notify(mqd, &sigev);
    
    	flags = O_RDWR | O_CREAT;
    	//gcc 컴파일시 gcc mesque.c -lrt
    	//로 해야 컴파일 됨.
    	mqd = mq_open(quename, flags, 0666, &attr);
    	size_t len = sizeof(messageptr);
    	//mq_send(mqd, messageptr, len, 10);
    	//sleep(1);
    
    
    	//넣은 메세지를 확인
    	//mq_receive(mqd, buff, attr.mq_msgsize, &priorecv);
    	//printf("받은 메세지는\n %s를 %d 우선 순위로\n", buff, priorecv);
    	//mq_receive(mqd, buff, attr.mq_msgsize, &priorecv);
    	//printf("받은 메세지는\n %s를 %d 우선 순위로\n", buff, priorecv);
    	for(;;)
    		pause();
    	mq_close(mqd);
    	return 0;
    }
    
    void sig_usr1(int mysig){
    	//signal hanlder로 message receive..
    
    	//한번 사용한 noty는 다시 등록.
    	mq_notify(mqd, &sigev);
    	mq_receive(mqd, buff, attr.mq_msgsize, &priorecv);
    	printf("받은 메세지는\n %s를 %d 우선 순위로\n", buff, priorecv);
    	return;
    
    
    
    }
    
    pi@raspberrypi:~/Project/cCode/IPC $ cat mesquesender.c 
    //message que header
    #include <unistd.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    #include <stdlib.h>
    #include <signal.h>
    #define MAX_SIZE 100
    
    
    mqd_t	mqd;
    struct mq_attr attr;
    int priorecv;
    char buff[100];
    
    int main(int argc, char** argv){
    	int		c, flags;
    	int prio;
    	char const *quename="/tmp_message";
    	char messageptr[50]= "this is a test.";
    	//메세지 큐 초기화
    	attr.mq_flags = 0;
        attr.mq_maxmsg = 10;
        attr.mq_msgsize = MAX_SIZE;
        attr.mq_curmsgs = 0;
    
    	flags = O_RDWR | O_CREAT;
    	//gcc 컴파일시 gcc mesque.c -lrt
    	//로 해야 컴파일 됨.
    	mqd = mq_open(quename, flags, 0666, &attr);
    	size_t len = sizeof(messageptr);
    
    	prio = atoi(argv[1]);
    	mq_send(mqd, messageptr, len, prio);
    	mq_close(mqd);
    	return 0;
    }
    
    pi@raspberrypi:~/Project/cCode/IPC $ mv mesque.c mesquereceive.c
    pi@raspberrypi:~/Project/cCode/IPC $ gcc -lrt mesquereceive.c -o recv
    pi@raspberrypi:~/Project/cCode/IPC $ gcc -lrt mesquesender.c -o send
    pi@raspberrypi:~/Project/cCode/IPC $ cat /dev/mqueue/tmp_message 
    QSIZE:0          NOTIFY:0     SIGNO:0     NOTIFY_PID:0     
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 
    세그멘테이션 오류
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 10
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 20
    pi@raspberrypi:~/Project/cCode/IPC $ cat /dev/mqueue/tmp_message 
    QSIZE:100        NOTIFY:0     SIGNO:0     NOTIFY_PID:0     
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 100
    pi@raspberrypi:~/Project/cCode/IPC $ ./recv 
    ^Z
    [1]+  Stopped                 ./recv
    pi@raspberrypi:~/Project/cCode/IPC $ bg
    [1]+ ./recv &
    pi@raspberrypi:~/Project/cCode/IPC $ cat /dev/mqueue/tmp_message 
    QSIZE:150        NOTIFY:0     SIGNO:0     NOTIFY_PID:0     
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 15
    pi@raspberrypi:~/Project/cCode/IPC $ bg
    -bash: bg: job 1 already in background
    pi@raspberrypi:~/Project/cCode/IPC $ jobs
    [1]+  Running                 ./recv &
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 20
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv 
    16120
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    받은 메세지는
     this is a test.를 100 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    받은 메세지는
     this is a test.를 20 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    받은 메세지는
     this is a test.를 20 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    받은 메세지는
     this is a test.를 15 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    받은 메세지는
     this is a test.를 10 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ pidof recv |xargs kill -10
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 100
    받은 메세지는
     this is a test.를 100 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ cat /dev/mqueue/tmp_message 
    QSIZE:0          NOTIFY:0     SIGNO:10    NOTIFY_PID:16120 
    pi@raspberrypi:~/Project/cCode/IPC $ ./send 10
    받은 메세지는
     this is a test.를 10 우선 순위로
    pi@raspberrypi:~/Project/cCode/IPC $ cat /dev/mqueue/tmp_message 
    QSIZE:0          NOTIFY:0     SIGNO:10    NOTIFY_PID:16120 
    pi@raspberrypi:~/Project/cCode/IPC $ 
    
    https://www.joinc.co.kr/w/Site/system_programing/IPC/MessageQueue

    gcc 기본 컴파일하면 에러를 본다. 옵션 넣어야 한다. -lrt.

    https://stackoverflow.com/questions/19964206/weird-posix-message-queue-linking-issue-sometimes-it-doesnt-link-correctly