c++ マルチスレッド 並列処理

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 987

daisuke0203

score 7

以下の要件を満たすプログラムを教えてください。
////////////////////////////////////////////

  1. C++言語
  2. OpenCVを使用
  3. 1台のwebカメラ(外付け・PC内蔵どちらもOK)を使用
  4. 以下のようにスレッドを分けて動作させる

a. 4つのスレッドで並列処理を行う
b. スレッド1は、カメラから画像を取得する
c. スレッド2は、スレッド1で取得した画像を表示する
e. スレッド2は、ユーザーのキーボード入力を待ち受ける(cv::waitKey)
f. スレッド2は、キーボードの"2"を押されたら、カメラ画像を"th2.png"という名前で保存する

g. スレッド3とスレッド4は、スレッド1とスレッド2と同じ関係である 
h. スレッド3は、カメラから画像を取得する
i. スレッド4は、スレッド1で取得した画像を表示する
j. スレッド4は、ユーザーのキーボード入力を待ち受ける(cv::waitKey)
k. スレッド4は、キーボードの"4"を押されたら、カメラ画像を"th4.png"という名前で保存する

l. キーボードで"esc"が押されたらプログラムを終了する
///////////////////////////////////////////
以下のようなプログラムを作成しましたがうまく動きません. 

#include "pch.h"
#include<thread>
#include<iostream>
#include<opencv2/videoio.hpp>
#include<opencv2/opencv.hpp>
#include<mutex>

using namespace std;
using namespace cv;

mutex m1, m2;
const std::string WIN_NAME = "Capture";
cv::VideoCapture cap(0);
int inp_key = cv::waitKey(1);
cv::Mat frame;
cv::Mat frame2;

void thfunc1() {

        unique_lock<mutex> lock(m1);
        cap >> frame;

}

void thfunc2() {
    while (1)
    {
        unique_lock<mutex> lock(m1);
        cv::imshow(WIN_NAME, frame);
        int inp_key = cv::waitKey(1);
        if (inp_key == 50)  cv::imwrite("th2.png", frame);
    }
}


void thfunc3() {
    unique_lock<mutex> lock(m2);
    cap >> frame2;
}

void thfunc4() {
    while (1)
    {
        unique_lock<mutex> lock(m1);
        cv::imshow(WIN_NAME, frame);
        if (inp_key == 52)  cv::imwrite("th4.png", frame);
    }
}

int main(int argh, char* argv[])
{

    while (1)
    {
        thread th1(thfunc1);
        thread th2(thfunc2);
        thread th3(thfunc3);
        thread th4(thfunc4);

        // [ESC]
        if (inp_key == 27) break;

        th1.join();
        th2.detach();
        th4.detach();
        th3.join();
    }



    cv::destroyAllWindows();
    return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • y_waiwai

    2019/01/02 17:01

    うまく動かないというのは、どういうふうに動くんでしょうか

    キャンセル

  • bochan2

    2019/01/02 17:07

    よく頑張りましたね
    プリントを入れるなどして原因を絞り込んでいただけると解決の役に立つと思います

    キャンセル

  • daisuke0203

    2019/01/02 17:19

    2つ問題点があります。
    1つは、連続してカメラの映像を表示させたいのですが途切れ途切れになってしまう。
    もう1つは、スレッド2だけ機能しスレッド4が機能しないことです。

    キャンセル

  • episteme

    2019/01/02 19:41

    ...期待通りに動くとは思えないんだが。
    たとえば thrfunc1 が必ず thrfunc2 に先立って動く保証はあるのかしら?

    キャンセル

回答 1

checkベストアンサー

0

生産者-消費者モデルを適応してmutexでのロックを短くしてあげたいところです。

main:

キュー1から取り出してcv::imshowに渡しつつ、キーボードイベントを受け取り、それによってキュー2に積む、もしくは各threadに終了通知

thread1:

cameraから読み取り、キュー1に積む

thread2:

キュー2から取り出してcv::imwriteでファイル書き出し


と思ったけどBoost.Fiberかなにかを使うべき案件か?(使ったことない


ところでcv::imshowってどのくらい速度出るのかな・・・?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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