それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

POSIX の メッセージ・キューを作成する(C言語)

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 とやり取りしてみる

前に作った、Pythonposix_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はホントわかりやすい。

参考資料