- blogs:
- cles::blog
2018/04/26
POSIX Message Queue を使ってプロセス間通信をする
c posixC 言語から簡単に使える MQ がないかと思って調べてみたら、POSIX Message Queue が恐ろしく便利だったのでメモ。
動作については Java のBlockingQueueをプロセスを跨いで使えるようなイメージです。
† サンプルプログラム
今回のプログラムは送信側 qsend と受信側 qrecv の2つに分かれています。
qsend は 0, 1, 2・・・ というように文字表示しながら、その文字を /testq という Queue に書き込み続けるプログラムになっています。
対になる qrecv は /testq という Queue から文字を取り出して表示を行います。
今回は Queue のサイズを 10 に設定しているので、溜まっているメッセージの数が 10 個になると qsend は mq_send() 部分でブロックし、Queue が空くのを待ちます。qrecv は溜まっているメッセージの数が 0 個になると、mq_receive() 部分でブロックし、新しいメッセージの到着を待ちます。
一見、機能はパイプと大差ない感じに見えるかもしれませんが、このプログラムはどちらから起動しても大丈夫です。
また、qsend, qrecv 共に複数個起動しても問題なく動作します。
qsend.c
#include <mqueue.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define QNAME "/testq"
int main(){
int cnt = 0;
int ret;
char str[100];
char *buff;
mqd_t q;
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 10;
attr.mq_msgsize = 1024;
attr.mq_curmsgs = 0;
mode_t omask;
omask = umask(0);
q = mq_open(QNAME, (O_WRONLY | O_CREAT), 0777, &attr);
umask(omask);
if ( q == -1 ){
printf("[ERROR]%d: %s\n", errno, strerror(errno));
return 1;
}
while(1){
sprintf(str ,"%d", cnt++);
buff = (char *)calloc(strlen(str) + 1, sizeof(char));
strcpy( buff, str );
printf("%s\n", buff);
ret = mq_send( q, buff , strlen(buff) , 0);
if ( ret == -1 ) {
printf("[ERROR]%d: %s\n", errno, strerror(errno));
return 1;
}
free(buff);
sleep(1);
}
}
qrecv.c
#include <mqueue.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define QNAME "/testq"
int main(){
mqd_t q;
struct mq_attr attr;
char *buff;
ssize_t n;
int i;
q = mq_open(QNAME, O_RDONLY);
if ( q == -1 ){
printf("[ERROR]%d: %s\n", errno, strerror(errno));
return 1;
}
while(1){
mq_getattr( q ,&attr );
buff = (char *)malloc(attr.mq_msgsize);
n = mq_receive( q, buff, attr.mq_msgsize, NULL);
if ( n == -1 ) {
printf("[ERROR]%d: %s\n", errno, strerror(errno));
return 1;
}
for (i = 0; i < n; i++) putchar(buff[i]);
putchar('\n');
fflush(stdout);
free(buff);
}
}
† コンパイルと実行
以下のオプションでコンパイルし、./qsend と ./qrecv を好きなだけ起動すれば動作がわかります。
gcc qrecv.c -lrt -o qrecv
gcc qsend.c -lrt -o qsend
† 参考
トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/10135
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
サイト内検索
検索ワードランキング
へぇが多いエントリ
- シャープの空気清浄加湿器の... (1)
- SMARTEK デジタル温湿度計 (1)
閲覧数が多いエントリ
1 . NP_TrackBack v2.x系の使い方(16594)
2 . Word で数式がグレーアウトされていて挿入できないときは(15267)
3 . awk で指定した n カラム目以降を出力する(11792)
4 . アーロンチェアのポスチャーフィットを修理(11582)
5 . Windows 10 で勝手にログアウトされないようにする(9786)
2 . Word で数式がグレーアウトされていて挿入できないときは(15267)
3 . awk で指定した n カラム目以降を出力する(11792)
4 . アーロンチェアのポスチャーフィットを修理(11582)
5 . Windows 10 で勝手にログアウトされないようにする(9786)
cles::blogについて
Referrers