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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

並列処理

複数の計算が同時に実行される手法

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

解決済

1回答

7265閲覧

マルチスレッド処理(非同期)をしたいのですが、エラーコードC2893が消えません。

Ta_42

総合スコア1

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

並列処理

複数の計算が同時に実行される手法

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

0クリップ

投稿2020/06/22 09:51

前提・実現したいこと

画像処理の勉強をしており、マルチスレッドを使って複数の動作を同時に行いたいと考えております。
すでに動作確認済みの二つのプログラムをマルチスレッドで行ったところ以下2点のエラーが出ました。

素人判断ですが、関数たちはもともと動いていたため悪さをしていないと思い簡素なコードを載せております。判断に必要なデータがありましたら教えてください。

発生している問題・エラーメッセージ

error C2893: 関数テンプレート 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)' の特定に失敗しました error C2672: 'std::invoke': 一致するオーバーロードされた関数が見つかりませんでした。

該当のソースコード

C++

1 2#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API 3#include <opencv2/opencv.hpp> 4#include <fstream> 5#include <iostream> 6#include <sstream> 7#include <iomanip> 8#include <thread> 9 10int ThradProcess1(int argc, char* argv[]) try { 11 12 画像を表示するプログラム。 13 14 } 15 16 return EXIT_SUCCESS; 17} 18catch (const rs2::error& e) 19{ 20 std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl; 21 return EXIT_FAILURE; 22} 23catch (const std::exception& e) 24{ 25 std::cerr << e.what() << std::endl; 26 return EXIT_FAILURE; 27} 28 29void save_frame_depth_data(const std::string& filename, 30 rs2::frame frame, 31 float depth_units) 32{ 33   csvファイルに画像の距離情報を書きこむプログラム 34} 35 36 37int ThradProcess2(int argc, char* argv[]) try 38{ 39  ・ 40  ・ 41  ・ 42 while (true) 43 { 44    . 45    . 46    . 47    //csvファイルに画像の距離情報を書きこむ関数の呼び出し 48 save_frame_depth_data("depth", depth, depth_units); 49 50 } 51 52 return EXIT_SUCCESS; 53} 54catch (const rs2::error& e) 55{ 56 std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl; 57 return EXIT_FAILURE; 58} 59catch (const std::exception& e) 60{ 61 std::cerr << e.what() << std::endl; 62 return EXIT_FAILURE; 63} 64 65int main() { 66 std::thread th1(ThradProcess1); 67 std::thread th2(ThradProcess2); 68 69 th1.join(); 70 th2.join(); 71} 72

補足情報(FW/ツールのバージョンなど)

  1. OS:Windows10
  2. IDE:Microsoft Visual Studio Community 2019
  3. 開発言語:C++

当方、プログラム並びにTeratail質問初心者なため
基本的な間違いや失礼がありましたらそちらもご教授いただけると幸いです。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2020/06/22 10:01

検索ワード「error C2672 std::invoke」で検索するといろいろなサイトがヒットしますが、試してダメだったものがありますでしょうか。もしあるようでしたらそれを明記していただいた方が、アドバイスする側も余計な回り道をしなくて済むと思います。
Ta_42

2020/06/22 12:11

ご指摘ありがとうございます。 調べても理解が追いつかずこちらに質問した次第で、何かを試すまでには至っておりません。 抽象度の高い質問で申し訳ないのですが、お力添えいただけると幸いです。
guest

回答1

0

ベストアンサー

int ThradProcess1(int argc, char* argv[])
int ThradProcess2(int argc, char* argv[])

なんだから、スレッドには引数与えにゃならんのでしょ?

std::thread th1(ThradProcess1);
std::thread th2(ThradProcess2);

ここで引数食わせてあげなよ。

おそらくは:

C++

1int main(int argc, char* argv[]) { 2 std::thread th1(ThradProcess1, argc, argv); 3 std::thread th2(ThradProcess2, argc, argv); 4 5 th1.join(); 6 th2.join(); 7}

[追記] こんなことがやりたいのかな:

C++

1#define _CRT_SECURE_NO_WARNINGS 2#include <thread> 3#include <iostream> 4#include <string> 5#include <cstring> 6 7int ThradProcess1(int argc, char* argv[]) { 8 if ( argc < 2 ) return -1; 9 for ( int i = 1; i < argc; ++i ) { 10 std::cout << (std::string(argv[0]) + " は " + argv[i] + " を画面に描くよ!\n"); 11 } 12 return 0; 13} 14 15int ThradProcess2(int argc, char* argv[]) { 16 if (argc < 3) return -1; 17 std::cout << (std::string(argv[0]) + " は " + 18 argv[1] + " の距離情報を " + 19 argv[2] + " に書き込むよ\n"); 20 return 0; 21} 22 23int make_argv(char* commandline, char* argv[]) { 24 int argc = 0; 25 for ( char* token = strtok(commandline, " "); token; token = strtok(NULL, " ")) { 26 argv[argc++] = token; 27 } 28 return argc; 29} 30 31int main() { 32 char command1[] = "ThreadProcess1 picture.png"; 33 char* argv1[8]; 34 int argc1 = make_argv(command1, argv1); 35 std::thread thread1(ThradProcess1, argc1, argv1); 36 37 char command2[] = "ThreadProcess2 objects.png distance.csv"; 38 char* argv2[8]; 39 int argc2 = make_argv(command2, argv2); 40 std::thread thread2(ThradProcess2, argc2, argv2); 41 42 thread1.join(); 43 thread2.join(); 44 std::cout << "おしごとおしまい\n"; 45}

実行結果:

ThreadProcess1 は picture.png を画面に描くよ! ThreadProcess2 は objects.png の距離情報を distance.csv に書き込むよ おしごとおしまい

投稿2020/06/22 10:37

編集2020/06/22 23:08
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ta_42

2020/06/22 12:35

コメントありがとうございます。確かに、引数を与えていませんでしたね。 (int argc, char* argv[])は言葉上の意味程度は理解しているのですが、どのような引数を与えればよいのかが分かりません。 理解せず、試しに std::thread th1(ThradProcess1,100, 100); std::thread th2(ThradProcess2,100,100); としてみたのですが、同様のエラーが出ます。 ちなみに、引数なしで int ThradProcess1() int ThradProcess2() として、 std::thread th1(ThradProcess1); std::thread th2(ThradProcess2); とすると、ビルドでき実行できるのですが、一瞬で固まります。 int argc, char* argv[]にはどのような値を与えればいいのでしょうか。
Ta_42

2020/06/22 12:45

すみません、提示してもらえてましたね。 急いでいたもので、見落としていました。 ありがとうございます、無事ビルドできました。 デバッグだと動かず、出来上がった.exeファイルを開くとそれっぽい動作をする微妙な状況なので、また質問に上がるかもしれません。
episteme

2020/06/22 12:55

元々の二つのプログラムそれぞれに与えてた引数と同じもん食わせばええんですけど...
Ta_42

2020/06/22 14:16

説明不足ですみません。それぞれ別のプログラムとして、 例えば、 ”画像のストリーミング.cpp” int main(int argc, char* argv[]){ } ”画像のデータをファイルに書き起こし.cpp” int main(int argc, char* argv[]){ } のように、もともと別のプログラム上でmain関数として扱っていたものを int ThradProcess1(int argc, char* argv[]) int ThradProcess2(int argc, char* argv[]) として、一つの実行ファイル上で動かそうと思ったので 別の関数の中で、int argc, char* argv[]に値を与えるということをしてないもんでして
episteme

2020/06/22 20:22

元々の”画像のストリーミング”プログラムには実行時のコマンドラインに何を与えてたんでしょか。それをそのまま渡せばいいハズだけど。 # 他方も同様
Ta_42

2020/06/23 13:23

コマンドラインからではなく、直接ファイルを開いて動かしていたので 特に、引数を食わせることはしてなかったです。習わし程度に(int argc, char* argv[])と書いていたもので… episteme様のご指摘通り訂正を加えるとビルドできたのですが、実行の仕方で挙動が異なる結果となります。具体的には、 コマンドプロンプトから実行: ”画像のデータをファイルに書き起こし”のみ起動、”画像のストリーミング””はウィンドウだけ表示されて映像なし フォルダから直接実行: ””画像のデータをファイルに書き起こし”は動かず、”画像のストリーミング””は正常に作動 つまり、どちらかのスレッドしか動いていないという状況になりました。これは、二つのスレッド同士で同じデータを使おうとして起きているという別問題かもしれません。 当初の質問は解決したと思はれるのですが、こういう場合は一度閉じて 別の質問を立てるべきでしょうか? プログラムに関係ない質問で申し訳ありません。
episteme

2020/06/23 22:39

> 引数を食わせることはしてなかったです。 なら void ThreadProcess() { ... } で十分。 > これは、二つのスレッド同士で同じデータを使おうとして起きているという別問題かもしれません。 それぞれが異なるファイルを処理対象とすれば状況は変わるかもですね。 > こういう場合は一度閉じて別の質問を立てるべきでしょうか? コンパイル・エラーは解消されましたからねぇ...
Ta_42

2020/06/24 11:31

では、episteme様の回答をベストアンサーに選ばせていただき この質問を終わりたいと思います。 知識の浅さ丸出しの質問にも関わらず、丁寧にお答えいただきありがとうございます。助かりました。 追記の内容も(int argc, char* argv[])の用途を理解するのにとても分かりやすかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問