質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

C++で、キューを監視したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,867

torimingo

score 78

C++で、queueにデータがpushされたことを監視する方法って、どんなものがありますか?
いま、わたしが実装しているのは、whileによる無限ループで、ループ毎にqueueからpopするようにしています。
この方法だと、冗長だという気がしてなりません。
FDを監視するselectみたいなものは、ありませんでしょうか?

コードを以下に掲載します。
msg_receive()のなかで、whileループでメッセージキュー(msgq)を監視しているところを改善したいです。

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <string>
#include <queue>

using namespace std;

queue<string> msgq;
pthread_mutex_t msgmutex = PTHREAD_MUTEX_INITIALIZER;

// メッセージ受信
void *msg_receive(void *arg){
    while(true){
        if(!msgq.empty()){
            pthread_mutex_lock(&msgmutex);
            cout << "      Receive Thread pop data : " << msgq.front() << endl;
            msgq.pop();
            pthread_mutex_unlock(&msgmutex);
            usleep(1500000);    // 1.5秒
        }
    }
    pthread_exit((void *)0);
}

// メッセージ送信
void *msg_send(void *arg) {
    string msg;

    while(true){
        cin >> msg;
        pthread_mutex_lock(&msgmutex);
        msgq.push(msg);
        pthread_mutex_unlock(&msgmutex);
    }
    pthread_exit((void *)0);
}

int main(int argc, char **argv) {
    pthread_t thr1, thr2;

    // 受信スレッド、送信スレッドを生成
    if(pthread_create(&thr1, NULL, msg_receive, NULL) ||
        pthread_create(&thr2, NULL, msg_send, NULL)){
        cout << argv[0] << "qthread_create() is failed\n";
        exit(1);
    }

    // スレッドの終了を待つ
    pthread_join(thr1, NULL);
    pthread_join(thr2, NULL);
    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2018/12/30 13:42

    なんのqueueのはなしでしょうか

    キャンセル

  • torimingo

    2018/12/30 15:28

    C++の#include<queue>のことです。
    質問にコードを追記しました。

    キャンセル

回答 3

+4

こんにちは。

最近では条件変数を使うと良いように思います。条件変数 Step-by-Step入門は条件変数を使ってQueueを実装するサンプルを使って解説してあります。

セマフォのP/V操作をうまいこと使ってキューを実装する方式も「常道」なのですが、参考となるサイトが見つかりませんでした。実装は簡単なのですが考え方がちょっと難しいです。

条件変数はかなり強力なツールですし、C++11以降標準で使えます。(セマフォはC++11でも導入されていません。条件変数があれば十分だからかも。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/30 23:19

    セマフォ版のキュー操作アルゴリズムは https://qiita.com/yohhoy/items/aa11116390d6bb0225e2 に(疑似)コードがありますのでご参考に...

    キャンセル

  • 2018/12/31 00:12

    >Chironianさん
    ご回答のほど、ありがとうございました。
    条件変数というものを初めて知りました。まさに自分が探していたものです。
    提示して頂いたサイトで非常にわかりやすく説明されていたので、勉強させて頂きたいと思います。

    >yohhoyさん
    セマフォ版のキュー操作アルゴリズムのコードを提示して頂き、ありがとうございます。
    さっと見ただけでは、まだ理解が及びませんでしたので、自分でも色々と調べていきたいと思います。

    キャンセル

checkベストアンサー

+1

セマフォ使えばいいんじゃないですか。

push側は

pthread_mutex_lock(&msgmutex);
msgq.push(msg);
pthread_mutex_unlock(&msgmutex);
/* ここにセマフォのV操作を記述する */

pop側は

while(true) {
    /* ここにセマフォのP操作を記述する */

    pthread_mutex_lock(&msgmutex);
    cout << "      Receive Thread pop data : " << msgq.front() << endl;
    msgq.pop();
    pthread_mutex_unlock(&msgmutex);
}

OSなどの環境がわからないのでセマフォ操作のコードはコメントにしています。
ググったり以下のURLを参考にするなどしてご自分の環境に合わせて実装してください。
http://www.c-lang.net/semop/index.html
https://msdn.microsoft.com/ja-jp/library/cc429076.aspx

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/30 22:24

    ご回答をありがとうございました。
    セマフォを使って、がんばってみたいと思います。

    キャンセル

+1

sizeを監視してればいいだけなんでは

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/30 18:19

    selectでsizeを監視することは、可能なのでしょうか。
    fdにsizeを設定してselectで監視してみたのですが、queueにデータを詰めても反応しませんでした・・・。

    キャンセル

  • 2018/12/30 19:01

    sizeでいくつキューに溜まったか見れるので、希望する分だけ溜まったかそうでないかの判定はできるでしょ

    キャンセル

  • 2018/12/30 19:59

    すみません。よく理解することができないのですが、sizeの監視方法をコードで示していただけないでしょうか。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る