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

코멘트

댓글 남기기

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.