問題タブ [stdthread]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - main() が終了すると、切り離されたスレッドはどうなりますか?
std::thread
を開始し、次にそれを開始すると仮定するとdetach()
、スレッドはstd::thread
、かつてそれを表していた が範囲外になっても実行を続けます。
さらに、切り離されたスレッド1に参加するための信頼できるプロトコルがプログラムにないため、終了時に切り離されたスレッドが引き続き実行されると仮定しmain()
ます。
標準 (より正確には、N3797 C++14 ドラフト) には、何が起こるべきかを説明するものは何も見つかりません。
1別の、おそらく同等の質問は、「切り離されたスレッドを再び参加できるか」です。これは、参加するために発明しているプロトコルが何であれ、スレッドがまだ実行されている間にシグナリング部分を実行する必要があり、OS スケジューラがスレッドが実際に終了したことを受信側が確実に検出する方法がないため、シグナリングが実行された直後にスレッドを 1 時間スリープさせることにしました。
main()
分離されたスレッドが実行されている状態で不足することが未定義の動作である場合、メインスレッドが決して終了しない限り、 の使用は未定義の動作です2。std::thread::detach()
したがって、切り離されたスレッドが実行されている状態で不足すると、定義された効果が発生main()
するはずです。問題は、 ( C++ 標準では、POSIX ではなく、OS ドキュメントではなく、...) これらの効果が定義されている場所です。
2切り離されたスレッドを結合することはできません ( の意味でstd::thread::join()
)。切り離されたスレッドからの結果を待つことはできますが (たとえば、future from を介してstd::packaged_task
、またはカウント セマフォまたはフラグと条件変数によって)、スレッドが の実行を終了したことを保証するものではありません。実際、シグナル部分をスレッドの最初の自動オブジェクトのデストラクタに入れない限り、一般に、シグナル コードの後に実行されるコード (デストラクタ) が存在します。切り離されたスレッドが上記のデストラクタの実行を終了する前に、OS がメイン スレッドが結果を消費して終了するようにスケジュールした場合、何が起こると定義されていますか?
c++ - std::thread コンストラクター (変数の量)
こんにちは、プログラムに少し問題があります (配列をスカラーで乗算したい)。
基本的に、乗算スタッフ(要素ごと)を実行するスレッドのベクトルを作成したい
コードサンプル
最初の mainImplementation 関数
}
スカラー乗算を実装する now 関数
}
この部分はまだ実装していませんが、1 つの問題を解決できません
ラインで
コンパイラはそこに問題があると言っています
「エラー: コンストラクター std::thread::thread のインスタンスが引数リストと一致しません」。
この問題を解決できないようです。参照によってスレッドコンストラクターの関数に変数を渡す必要があることを読んだので、これはここでは問題ではないと思います。乗算関数に6つの変数を渡すので、問題ないはずですが、そうではなく、ここで何をすべきかわかりません...同様の問題を検索したため、Googleも私を助けることができません。
助けてくれてありがとう。
c++ - std::thread が終了するのを待っています
プログラムの終了時に適切にクリーンアップしようとしているので、終了するのを待つように呼び出しjoin()
ています。std::thread
これは単にメインスレッドを永遠にブロックしているように見えますが、ワーカースレッドは次のような (ほぼ) 空のループであるため、その理由はわかりません。
もちろん、ing のrun
前に false に設定しています。join
今、私はそれがメンバー関数であり、オブジェクトの破壊時に呼び出されることに関係があるのではないかと疑っています。私は次のようなスレッドを作成していrunThread.reset(new thread(&GameLoop::Run, this));
ますrunThread
: 呼び出しは、オブジェクトのデストラクタで行われます。unique_ptr<std::thread>
GameLoop
join()
GameLoop
オブジェクトが破棄される過程にある場合、ループ スレッドが終了できないのではないでしょうか? デバッガーによると、ループ スレッドは の暗い深さに残りますmsvcr120d.dll
。もしそうなら、あなたはそれをどのように扱いますか?
注意:std::thread
ここは初めてです!
更新:これは、デストラクタに参加するための私の呼び出しです:
更新 2:を削除すると、 !join()
によって例外が発生します。~thread()
c++ - C++ 11 の std::thread 終了時に関数を自動的に呼び出す
std::thread
現在のスレッドが終了したときに関数 (またはラムダ関数) の呼び出しが自動的に行われるように設定したいのですが、スレッド作成のタスク全体を引き継ぐか、手動で確認しない限り、それを行う方法がわかりません。すべてのスレッドは、私が常に最後の操作として提供する特定の関数を呼び出します。
基本的に、プロトタイプが次のようなものに似ている関数が必要です。
これは、on_thread_exit を呼び出したスレッドが最終的に終了したときに特定の関数が自動的に呼び出されるようにするために必要なセットアップを実行し、スレッドの作成または終了時に特定の関数を明示的に呼び出す必要はありません。
c++ - 新しいスレッドの作成時にコンストラクター呼び出しをコピーする
スレッド化と C++ メモリ モジュールの詳細を学ぶために、C++ Concurrency in Action という本を読んでいます。次のコードでコピー コンストラクターが呼び出される回数に興味があります。
Visual Studio 2013 デバッガーでこのコードを確認すると、コピー コンストラクターが 4 回呼び出されていることがわかります。メインスレッドから 3 回呼び出され、次に新しいスレッドから 1 回呼び出されます。新しいスレッドのオブジェクトのコピーを作成したため、1 つを期待していました。3 つの余分なコピーが作成されるのはなぜですか?
c++ - 別のスレッドによって既にロックされている場合、mutex::lock() はどのくらいの頻度でロック解除状態をチェックしますか?
cppreferenceによるstd::lock_guard
と、std::mutex
パラメータを使用して を構築すると、その のlock()
メソッドが呼び出されmutex
ます。
cplusplusによると、mutex
のメソッドに関してlock()
:
ミューテックスが別のスレッドによってロックされている場合、呼び出し元のスレッドの実行は、別のスレッドによってロックが解除されるまでブロックされます...
タイトルの質問が適切に表現されているかどうかわからないので、以下のコードのコンテキストに入れました。
これをテストして、呼び出し可能なスレッド (関数、ファンクター、ラムダなど) の実行を終了したり、例外をスローしたりするのではなく、呼び出し元のスレッドが実際にロック解除を待機するかどうかを確認したかったのです。次のコードには 2 つのスレッドt1
とがありt2
、それぞれが同じ関数へのポインタで構築されていますfoo
。への各呼び出しは、ロックで保護されたコードを実行する前に、のparameterによって決定さfoo
れるsleep_for
一定の時間になります。ロックで保護されたコード自体には、ブロックされた実行期間をより明確にするために、別の期間が含まれています。foo
unsigned
num
sleep_for
コンソール出力:
が出力されるまでに約/少なくとも 3.05 秒かかり5
ます。が出力されるまでに約/少なくともさらに 3 秒かかり10
ます。これはt2
、保護されたコードを最初に実行することを意味しmutex
ます。
foo
from threadへの呼び出しt1
がlock_guard
行に到達し、mutex
によって既にロックされていることが判明すると、実行を終了したり、例外をスローしたりしないと想定しています。ロックが解除されるのを待つだけです。t2
t1
t1
どのくらいの頻度でロック解除をチェックしますかstd::mutex::lock()
? std::lock_guard
小切手はどのくらいの費用がかかりますか? チェックは次のように実装されていますか?
c++ - std::thread 参照渡しによるコピー コンストラクターの呼び出し
std::thread を使用してスレッドにデータを渡す際に問題があります。コピーコンストラクタなどの一般的なセマンティクスは理解できたと思いますが、問題がよくわかっていないようです。したがって、コピーコンストラクターを非表示にした Log という単純なクラスがあります。
今、私はhttp://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_server.cppに大きく基づいたメインを持っています
main が関数サーバーを呼び出し、IOService、portNumber、およびロガーを渡すことがわかります。ロガーは参照によって渡されるため、次のようになります。
ロガー (またはソケット) を参照によってスレッドに渡そうとするとコンパイラ エラーが発生しますが、参照によって session() に渡すとエラーは発生しません。
これで、参照はポインタを渡すことと同じであることが正しく理解できたと思います。つまり、コピー コンストラクターを呼び出すのではなく、単にポインターを渡すだけで、構文的にはポインターではないかのように扱うことができます。
エラー C2248: 'Log::Log': クラス 'Log' で宣言されたプライベート メンバーにアクセスできません
1> \log.h(55) : 'Log::Log' の宣言を参照してください
1> \log.h(28) : 「ログ」の宣言を参照してください
...
: コンパイル中の関数テンプレートのインスタンス化 'std::thread::thread(_Fn,_V0_t &&,_V1_t)' への参照を参照してください
1>と
1> [
1> Fn=void ( _cdecl *)(boost::asio::ip::tcp::socket *,Log &),
1> _V0_t=boost::asio::ip::tcp::socket *,
1> _V1_t=ログ &
1> ]
ただし、ポインターを渡すように変更すると、すべてが満足します
参照渡しが私の copy constructor を呼び出すのはなぜですか。std::thread のために、ここで何か特別なことが起こっていますか? コピー コンストラクターと参照渡しを誤解していませんか?
例で行われているように std::move() を使用しようとすると、別の、しかし同様に不可解なエラーが発生します。VS2012 が C++11 を正しく実装していない可能性はありますか?
c++ - std::mutex ロックの順序
2 つの連続する式の間、関数の呼び出しとその本体の最初の式の実行の間、またはコンストラクターの呼び出しとその初期化子の実行の間で何が起こるかについて、私はめったに考えたことがありません。それから私は並行性について読み始めました...
1.)本体が同じオブジェクトの初期化でstd::thread
始まる、同じ callable (関数、ファンクター、ラムダなど) を持つ のコンストラクターへの 2 つの連続した呼び出しで、最初のコンストラクター呼び出しに対応するスレッドがロックを実行することを標準で保証しますか? -最初に保護されたコード?std::lock_guard
std::mutex
thread
2.) 標準が保証しない場合、2 番目のthread
コンストラクター呼び出しに対応するスレッドが最初に保護されたコードを実行する可能性は理論的または実際的にありますか? thread
(たとえば、最初のコンストラクター呼び出しのイニシャライザーまたは本体の実行中の重いシステム負荷)
これは、グローバルstd::mutex
オブジェクトm
と にunsigned
num
初期化されたグローバル1
です。foo
functionの本体の左中括弧{
と. の間には空白しかありませんstd::lock_guard
。には、 と のmain
2 つがstd::thread
ありt1
ますt2
。t1
最初にスレッド コンストラクターを呼び出します。t2
スレッド コンストラクタを 2 番目に呼び出します。各スレッドは へのポインタで構築されますfoo
。引数でt1
呼び出します。引数で呼び出します。どちらのスレッドが最初にロックするかに応じて、両方のスレッドがロック保護されたコードを実行した後、 の値は aまたは aになります。等しくなりますfoo
unsigned
1
t2
foo
unsigned
2
mutex
num
4
3
num
4
ロックにt1
打ち込む場合。t2
それ以外の場合は、num
に等しくなり3
ます。ループして各ループの最後にリセットすることで、num
これを 100,000 回試行しました。1
(私の知る限り、結果はどのスレッドがjoin()
最初に編集されるかに依存しませんし、依存すべきではありません。)
最終的には にcount
等しい100000
ので、t1
毎回レースに勝つことがわかります。しかし、これらの試験は何も証明しません。
3.) 「thread
コンストラクターを最初に呼び出す」という標準の命令は、常に「コンストラクターに渡された呼び出し可能オブジェクトを最初に呼び出す」ことを意味しthread
ますか?
4.) 「コンストラクターに渡された callable を最初に呼び出す」という標準の命令は、常に「最初にロックする」thread
ことを意味しますか? mutex
callable の本体内に、初期化の行の前に callable に渡されたパラメーターに依存するコードが存在しない場合はstd::lock_guard
? static
(また、特定の呼び出しを意図的に遅らせるために使用できる、呼び出された回数のカウンターなど、呼び出し可能オブジェクトのローカル変数も除外します。)
c++ - std::thread を匿名で宣言するにはどうすればよいですか?
次の短いプログラムを検討してください。
これは、コンパイルして実行します (永久に)。
コメントアウトされた行では、ここで説明されている手法を使用して、新しいスレッドを匿名で宣言しようとしています。ただし、その行がコメントインされると、コンパイルできますが、実行すると次のエラーが発生します。
スレッドを匿名で正しく宣言するにはどうすればよいですか?
注意してください、私はにいg++ 4.4.7
ます。