linuxCマルチプロセス通信---POSIXメッセージキュー


文書ディレクトリ
  • posixとsystem vの比較
  • POSIXプログラミング注意事項
  • 関連API
  • IPCオブジェクト
  • を作成または開く
  • •関数プロトタイプ:
  • •関数機能:
  • •関数パラメータ:
  • •関数戻り値
  • POSIXメッセージキュー
  • を閉じる.
  • •関数プロトタイプ:
  • •関数機能:
  • •TIPS:
  • •POSIXメッセージキューを削除する
  • •関数プロトタイプ:
  • •関数機能:
  • •POSIXメッセージキューへのメッセージの書き込み
  • •関数プロトタイプ:
  • •関数機能:
  • •関数パラメータ:
  • •POSIXメッセージキューからメッセージを読み出す
  • .
  • •関数機能:
  • •関数パラメータ:
  • •関数戻り値
  • 親子プロセスは、POSIXメッセージキュー通信
  • を通過する.
  • の2つの独立したプロセスは、POSIXメッセージキュー通信
  • を通過する.
  • receive
  • send

  • posixとsystem vの比較
    •POSIX IPC•POSIXインタフェースの方が簡単:ファイルI/Oのようなopen、close、unlinkなどのインタフェースを使用する•POSIXは名前の代わりにキーを使用してIPCオブジェクトを識別する•IPCオブジェクトへの参照カウントを使用して、IPCオブジェクトへの削除を簡略化する–ファイルと類似して、削除操作は、IPCオブジェクトの名前を削除するだけです.IPCオブジェクトの参照カウントが0になってから、IPCオブジェクト•System V IPC•System V IPCの移植性が向上します.ほとんどのUNIXシステムはsystem Vをサポートしています.POSIXはUNIXシステムではオプションのコンポーネントです.UNIXシステムではサポートされていないものもあります.LinuxシステムではシステムV・Linux 2.6がサポートされています.POSIXが続々とサポートされています.
    POSIXプログラミングの注意事項
    •POSIXメッセージキューと共有メモリを使用する場合は、リアルタイムライブラリlibrtリンク、コンパイル時に$-lrtを指定する必要があります•POSIX信号量を使用する場合は、スレッドライブラリlibpthreadにリンクする必要があります.コンパイル時に$-lpthreadを指定する必要があります
    関連API
    •mq_Open:メッセージキュー•mq_を作成または開くsend:メッセージ・キューにメッセージ・mq_を書き込むreceive:メッセージキューからメッセージ•mq_を読み込むclose:プロセスが開いているメッセージキューを閉じる•mq_unlink:メッセージキュー•mqを削除setattr:メッセージキューの追加プロパティを設定•mq_getattr:メッセージキューの追加プロパティ•mq_を取得nofity:非同期通知
    IPCオブジェクトの作成またはオープン
    •関数のプロトタイプ:
    –mqd_t mq_open (const char *name, int oflag); –mqd_t mq_open (const char *name, int oflag, mode_t mode, struct mq_attr *attr);
    •関数機能:
    指定した名前でオブジェクトを作成または開き、そのオブジェクトのハンドルを返します.
    •関数パラメータ:
    -name:作成または開くオブジェクトを識別します.-Oflag:O_CREAT/O_EXCL/O_RDONLY/O_WRONLY/O_RDWR/O_NONBLOCK–Mode:ビットマスク、パーミッション設定–Attr:メッセージキューのプロパティを設定し、NULLの場合はデフォルトのプロパティを使用します.Linux3.5以降のバージョンでも/procで設定を表示できます
    •関数の戻り値
    -成功:メッセージキューのIPCオブジェクト記述子を返す-失敗:-1を返しerrnoを設定する
    POSIXメッセージキューを閉じる
    •関数のプロトタイプ:
    int mq_close(mqd_t mqdes);
    •関数機能:
    ディスクリプタによるメッセージキューのクローズ
    •TIPS:
    -POSIXメッセージキューは、プロセスの終了またはexec()の実行時に自動的に閉じられます.
    •POSIXメッセージキューの削除
    •関数のプロトタイプ:
    int mq_unlink (const char *name);
    •関数機能:
    -nameで識別されたメッセージ・キューを削除します.すべてのプロセスがキューを使用した後、キューを破棄します.–キューを開いたすべてのプロセスがキューを閉じた場合は、すぐに削除します.
    •POSIXメッセージキューへのメッセージの書き込み
    •関数のプロトタイプ:
    int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio);
    •関数機能:
    msg_ptrが指すバッファ内のメッセージを記述子mqdesが参照するメッセージキューに追加
    •関数パラメータ:
    –mqdes:メッセージキュー記述子–msg_ptr:メッセージを格納するバッファへのポインタ–msg_len:メッセージの長さ[08192]–msg_prio:メッセージはキューに優先順位で並べられ、0に設定すると優先順位が不要になります
    •POSIXメッセージキューからメッセージを読み込む
    •ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
    •関数機能:
    -mqdesが参照するメッセージキューから、最も優先度が高く、保存時間が最も長いメッセージを削除します.削除したメッセージをmsg_に保存します.ptrポインタが指すバッファ
    •関数パラメータ:
    –mqdes:メッセージキュー記述子–msg_ptr:メッセージを格納するバッファへのポインタ–msg_len:msg_ptrが指すバッファ長は、メッセージキューのmq_よりも大きいmsgsize –msg_prio:空でない場合、受信したメッセージの優先度はポインタの方向にコピーされます.
    •関数の戻り値
    -成功:受信したメッセージのバイト数を返す-失敗:-1、errnoの設定
    親子プロセスがPOSIXメッセージキューを介して通信する
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define handle_error(msg) \
       do{perror(msg);exit(EXIT_FAILURE);}while(0)
    
    int main (void)
    {
    	mqd_t mq_id;
    	if ((mq_id = mq_open("/posix_msg_queue", O_RDWR | O_CREAT, 0644, NULL)) == -1)
            handle_error("mq_open");
    
        struct mq_attr mq_attribute;
    	if (mq_getattr (mq_id, &mq_attribute) == -1)
            handle_error("mq_getattr");
    	printf ("mq_flags: %ld
    ", mq_attribute.mq_flags); printf ("mq_maxmsg: %ld
    ", mq_attribute.mq_maxmsg); printf ("mq_msgsize: %ld
    ", mq_attribute.mq_msgsize); printf ("mq_curmsgs: %ld
    ", mq_attribute.mq_curmsgs); int ret_from_fork; ret_from_fork = fork (); if (ret_from_fork == 0) // child process { char msg_buf[mq_attribute.mq_msgsize]; memset (msg_buf, 0, mq_attribute.mq_msgsize); int count = 0; while (1) { if (mq_receive (mq_id, msg_buf, mq_attribute.mq_msgsize, NULL) == -1) handle_error("mq_receive"); printf ("child process received msg: %s
    ", msg_buf); sleep (1); if (++count % 10 == 0) break; } } else if (ret_from_fork > 0) //parent process { int count = 0; while (1) { if (mq_send (mq_id, "hello world", sizeof ("hello world"), 1) == -1) handle_error("mq_send"); printf ("parent process: send msg to mqueue success
    "); sleep (1); if (++count % 10 == 0) break; } } else handle_error("fork"); mq_close (mq_id); sleep (5); if (mq_unlink ("/posix_msg_queue") == -1) handle_error("mq_unlink"); return 0; }

    2つの独立したプロセスがPOSIXメッセージキューを介して通信する
    receive
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main (void)
    {
    	mqd_t mq_id;
    	if ((mq_id = mq_open("/posix_msg_queue", O_RDONLY | O_CREAT, 0644, NULL)) == -1)
    	{
    		perror ("mq_open");
    		exit (EXIT_FAILURE);
    	}
        struct mq_attr mq_attribute;
    	if (mq_getattr (mq_id, &mq_attribute) == -1)
    	{
    		perror ("mq_getattr");
    		exit (EXIT_FAILURE);
    	}
    
    	char msg_buf[mq_attribute.mq_msgsize];
    	memset (msg_buf, 0, mq_attribute.mq_msgsize);
    
    	while (1)
    	{
    		if (mq_receive (mq_id, msg_buf, mq_attribute.mq_msgsize, NULL) == -1)
    		{
    			perror ("mq_receive");
    			exit (EXIT_FAILURE);
    		}
    		printf ("%s
    ", msg_buf); sleep (1); } mq_close (mq_id); if (mq_unlink ("/posix_msg_queue") == -1) { perror ("mq_unlink"); exit (EXIT_FAILURE); } return 0; }

    send
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main (void)
    {
    	mqd_t mq_id;
    	if ((mq_id = mq_open("/posix_msg_queue", O_WRONLY | O_CREAT, 0644, NULL)) == -1)
    	{
    		perror ("mq_open");
    		exit (EXIT_FAILURE);
    	}
    	while (1)
    	{
    		if (mq_send (mq_id, "hello world", sizeof("hello world"), 1) == -1)
    		{
    			perror ("mq_receive");
    			exit (EXIT_FAILURE);
    		}
    		printf ("msg send success--------
    "); sleep (1); } mq_close (mq_id); return 0; }