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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

11052閲覧

スレッド内で無限ループを実現したい

askman

総合スコア26

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/28 05:08

前提・実現したいこと

c++の標準ライブラリであるstd::threadでメインスレッドとは別のスレッドでタイマーを動かしたいと考えています。しかし、std::threadのjoin()により呼び出したスレッドが終了するまで呼び出し元のスレッドが待機してしまうため、上手くタイマーを作れないです。この問題を回避する方法ないでしょうか?

該当のソースコード

c++

1#include <chrono> 2#include <thread> 3#include <iostream> 4using namespace std::chrono; 5 6void timer() { 7 while (1) { 8 auto time1 = high_resolution_clock::now(); 9 std::this_thread::sleep_for(milliseconds(1000)); 10 auto time2 = high_resolution_clock::now(); 11 12 auto ms = duration_cast<milliseconds>(time2 - time1); 13 std::cout << ms.count() << std::endl; 14 } 15} 16 17int main() { 18 std::thread th(timer); 19 th.join(); 20 while (1) { 21 //メイン処理 22 } 23 return 0; 24}

このメイン処理前のth.join()で待機してしまいます。

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

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

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

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

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

coco_bauer

2020/03/28 05:25

何がしたいのでしょうか? 実現しようとしているタイマーの機能が不明です。 timer関数の中は無限ループになっているので、「 std::cout << ms.count() << std::endl;」で約1秒おきに画面出力が出るのでしょう。それで、何が不満なのですか? timer関数は無限ループを実行するので終了することがありません。そんな関数を実行しているthreadをjoinしようとしたら永遠に待つしかないですよね。 どのような動きをするプログラムが作りたいのかを具体的に質問に付け加えると、回答が得られるのではないでしょうか?
askman

2020/03/28 05:45

簡単な例でいうと、メインのwhileループ内で一定時間ごとに処理を行うようなプログラムを組みたいのですが、sleep()を使っている間は他の処理もできなくなるためスレッドを使用して実現できないかと考えていました。
coco_bauer

2020/03/28 06:35

メインのwhileループ内で、定期的に(sleepを使って間を開けて)別スレッドで処理をさせれば良いのではないでしょうか? メインでsleepしている間も別スレッドの実行は進みますからね。
askman

2020/03/28 06:39

はい。ありがとうございます。クロック同期っていうのを使うことにしました。何も知らないゴミがここに質問書いてしまい迷惑かけて申し訳ありませんでした。
episteme

2020/03/28 06:43

一定時間が1s、処理が100msだとすると余った900msの間なにするんですか? なにもすることないならsleep_untilしてりゃいいんじゃないかと。
guest

回答1

0

ベストアンサー

join をメイン処理の前に呼ばなければいいです

cpp

1int main() { 2 std::thread th(timer); 3 while (1) { 4 //メイン処理 5 } 6 th.join(); 7 return 0; 8}

追記

それは並行とは呼びません。説明が難しいので詳細は検索してください。

やりたいことはおそらく「クロック同期」でしょう。
スレッドは使わないほうがいいです。こんな感じでどうでしょう

cpp

1int main() { 2 while (1) { 3 auto time1 = high_resolution_clock::now(); 4 //メイン処理 5 auto time2 = high_resolution_clock::now(); 6 auto ms = duration_cast<milliseconds>(time2 - time1); 7 std::this_thread::sleep_for(milliseconds(1000) - ms); 8 } 9 return 0; 10}

投稿2020/03/28 05:21

編集2020/03/28 05:59
yuki23

総合スコア1448

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

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

askman

2020/03/28 05:24 編集

すいません。メイン処理と並行して処理させていくような形を取りたいのです…
yuki23

2020/03/28 05:25

そうなると思いますが?
yuki23

2020/03/28 05:34

もしかして、「並行」という言葉の意味を誤解されてませんか? 一体何をしたいのか、具体的に説明してみてください
askman

2020/03/28 05:46

並行は並行です。それ以外言いようがありません
SaitoAtsushi

2020/03/28 06:00

質問文から読み取れる範囲では yuki23 さんの回答は完璧な答えに見えますが、このプログラム例で望ましくない挙動があるのであれば望ましくない結果が出る例 (while 文の中身) の形で示してもらえれば回答しやすいかと思います。
yuki23

2020/03/28 06:21

誤解している方が「誤解されてませんか?」と聞かれて「はい、誤解しています」などと答えるはずがないので、私の聞き方が悪かったです。ごめんなさい。 コンピュータ科学やプログラミングでは、「並行」という言葉を特別な意味で使います。その概念はとても難しいので、情報系の学生でも理解している人は半分以下だと思います。 askman さんはおそらくその意味を知らないと思いますので、そこで行き違いが起こっていると思います。なので、「並行」という言葉を使わずに、どういう動作をしてほしくて、何ができていないのかを、具体的なソースコードや入力・出力の例を交えて説明してみてください、ということです。
askman

2020/03/28 06:37

はい。並行すら知らないゴミが言葉として使ってしまい申し訳ありませんでした。使わないようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問