POSIXのメッセージ・キューをC言語で扱う
コンパイルには gcc -lrt
を使う。
まずは送信するところから。
q_push.c
#include <mqueue.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(){ int cnt; int ret; char *str; void *pt; mqd_t q; q = mq_open("/sample", O_WRONLY | O_CREAT ); while(1){ sprintf(str ,"%d", cnt++); printf("%s\n",str); pt = calloc(strlen(str) + 1,sizeof(char)); strcpy( pt, str ); ret = mq_send( q, pt , strlen(pt) , 0 ); if ( ret > 0 ) { perror("push error"); return; } sleep(1); } }
受信する所。
#include <mqueue.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(){ mqd_t q; struct mq_attr attr; void *buff; ssize_t n; char *str; q = mq_open("/sample", O_RDONLY | O_CREAT ); while(1){ mq_getattr( q ,&attr ); buff = malloc(attr.mq_msgsize); // n = mq_receive( q, buff, attr.mq_msgsize,NULL); // printf("read: %d bytes \n",n); printf("%s\n", (char*)buff); usleep(1000*100); free(buff); } }
コンパイル
$ gcc q_push.c -lrt -o q_push $ gcc q_pop.c -lrt -o q_pop
python とやり取りしてみる
前に作った、Python の posix_ipc を使ってキューを送信して受信してみる。
コンパイルしたバイナリで送信
takuya@:mq$ gcc q_push.c -lrt -o q_push takuya@:mq$ ./q_push 1 2 3 4 5 6 7 8
python で受信
takuya@:mq$ python q_pop.py 113 114 115 116 117 118 119
異なる言語でデータ交換
JSON でデータのやり取りも良いんだけど、ファイルロックを考慮したり、名前付きパイプでもいいんだけど、複数ワーカーをぱぱっと動かせる感じなのは、とてもいいよね。いちいちSQLを持ち出してキュー構造を作るのは不便だし。
ワーカープログラムが死んでもキューは残ってるし。POSIXのファイルベースなAPIはホントわかりやすい。
参考資料
- man mq_open
- man mq_send
- man mq_receive
- man mq_getattr
- http://d.hatena.ne.jp/s-kita/20080713/1215940088