問題タブ [pthreads]
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.
windows - pthreadとCreateThreadによるデッドロック
Windowsアプリケーションでpthreadを使用しています。プログラムがデッドロックしていることに気づきました。簡単に調べたところ、次のことが発生したことがわかりました。
スレッド1がスレッド2を生成しました。スレッド2がスレッド3を生成しました。スレッド2は、ロック解除されていないスレッド3からのミューテックスを待機していました。
そこで、gdbでデバッグし、3番目のスレッドをバックトレースすると次のようになりました。
どういうわけか、WindowsのCreateThread関数でスタック、デッドロックしました!明らかに、コードの実行を開始することさえできなかったとき、ミューテックスのロックを解除することはできませんでした。それでも、明らかにここでスタックしているという事実にもかかわらず、pthread_createはゼロ(成功)を返しました。
これを特に奇妙なものにしているのは、Linux上の同じアプリケーションにそのような問題がないことです。作成プロセス中にスレッドがハングする(!?)が、正しく作成されたかのように正常に戻る原因は、いったい何でしょうか。
編集:コードのリクエストに応じて、ここにいくつかのコードがあります(簡略化されています):
スレッドの作成:
b_thread_activeが設定されるまで待機することに注意してください。したがって、何らかの形でb_thread_activeが設定されているため、呼び出されるスレッドは何かを実行する必要があります...
...これがlookahead_thread関数です:
lookahead_slicetype_decide(h); スレッドが行うことです。
ミューテックス、synch_frame_list_get_size:
スレッド2のバックトレース:
c - C : 一度だけ呼び出される pthread データ固有のデストラクタ
マンページからpthread_key_create
:
オプションのデストラクタ関数を各キー値に関連付けることができます。スレッドの終了時に、キー値に NULL 以外のデストラクタ ポインタがあり、スレッドにキーに関連付けられた NULL 以外の値がある場合、ポイントされている関数は、現在関連付けられている値を唯一の引数として呼び出されます。スレッドの終了時に複数のデストラクタが存在する場合、デストラクタ呼び出しの順序は指定されていません。
関連するデストラクタを持つすべての非 NULL 値に対してすべてのデストラクタが呼び出された後、関連するデストラクタを持つ非 NULL 値がまだある場合は、プロセスが繰り返されます。未解決の非 NULL 値に対するデストラクタ呼び出しの少なくとも [PTHREAD_DESTRUCTOR_ITERATIONS] 回の反復の後、関連付けられたデストラクタにまだいくつかの非 NULL 値がある場合、実装はデストラクタの呼び出しを停止します。
NULL 以外のスレッド固有の値に対して "Hello World" を出力する単純なデストラクタを使用した小さな例を書きました。私が見る限り、このデストラクタは、デストラクタへの最初の呼び出しの後、スレッド固有の値がまだ NULL ではない場合でも、(少なくとも Linux の fedora と mac os x では) 1 回だけ呼び出されます。
私は何かを逃しましたか?(glibc では PTHREAD_DESTRUCTOR_ITERATIONS = 4)。
ここに私の小さな例があります:
c - pthreadが終了したときにプロセスが終了しないようにするにはどうすればよいですか?
私はCでサーバープログラムを作成しています。このプログラムでは、クライアントが接続するたびに、クライアントの要求を処理するための新しいpthreadを作成します。
ただし、すべてのスレッドが終了すると、exit()が呼び出されたかのように、プログラムが終了します。これは問題です-どうすればそれを克服できますか?
サーバーが稼働していて、2つのクライアントが接続しているとします。これらのクライアントが切断されると(つまり、両方のスレッドが終了すると)、サーバープロセスが終了します。私が欲しいのは、サーバーがソケット要求をaccept()し続けることです。通常、これはfork()とaccept()を使用すると機能します。親プロセスが無限にループするのではなく終了するように、私は何を間違っていますか?
コードは基本的に次のようになります。
また、これは私がすでに尋ねた質問(以下にリンク)からの同じプロジェクトです... select()とIPCの使用に多くの時間を費やした後、失敗した後、私はスレッドに渦を巻くと思いました共有アドレス空間。
親子IPCにCでパイプを使用すると、プログラムがブロックされます
また、このコードの多くはここから取得されました:http ://www.s5h.net/2006/06/27/pthread-socket-server-in-c/
linux - Linux スレッドのリソース リーク?
マルチスレッド Linux アプリケーションの 1 つで、スレッドを削除せずにアプリケーションが終了します。これにより、スレッド リソースのリークが発生しますか。このアプリケーションを 1 日のうちに何度も起動すると、システムがクラッシュしますか?
c - 関数ポインタを使用してスレッドからコールバックを呼び出す
c プログラム コンパイラ gcc
私は3つのファイルを持っています。main.c stop_watch.h および stop_watch.c
このプログラムは機能します。start_stopwatch を呼び出します。そして、時間の経過後に main.c timeout_cb() でコールバックします。実行する必要がある他のコードがあるため、メインでブロックしたくないので、これも別のスレッドで実行します。
1) g_start_timer の秒は常にゴミになります。ヒープ上に構造を作成することでこれを解決できたのではないかと思いました。とにかく私はこれを解決することができますか?ヒープに秒要素を作成することを考えていました。しかし、これはやり過ぎだと思います
2) このプログラムは問題なく動作しますが、メインの printf("=== timeout_cb: %p\n", timeout_cb); の行をコメントアウトすると、スタックダンプになります。
3) メモリを解放するのに最適な時期はいつですか。メインで解放していました。しかし、スレッドが終了する前にメモリが解放されると心配です。これにより、非常に予期しない結果が生じる可能性があります。この呼び出しの後、メモリを解放するために thread_join() を使用できると考えています。ただし、stop_watch.c で作成された thead_id を返す必要があります。stop_watch.c で作成された thread_id を返す方法はありますか
ご提案いただきありがとうございます。
main.c
stop_watch.h
stop_watch.c
c - pthreads で共有変数を読み書きするにはどうすればよいですか?
LinuxでC pthreadsを使用して、2つのスレッドがあります。1 つはデータを書き込み、もう 1 つはそれを読み取ります。変数を使用して、読み取りが許可されているときに読み取りスレッドを許可し、許可されているときに書き込みスレッドを許可しています。したがって、ミューテックスは「newData」と呼ばれるこのブール変数に適用されます。私の質問は、「if」条件内のアクセスの周りでミューテックスをロック/ロック解除する必要がありますか? どちらの方法でも機能しますが、この変数に対して書き込み/読み取りが重複する可能性が非常に低いという理由だけで考えています。私の質問をよりよく説明するために、両方の選択肢を示します。
スレッド 1:
スレッド 2:
2 番目のバージョンは機能しますが、正しいかどうかはわかりません。
スレッド 1:
スレッド 2:
c - pthread コールバックがユーザー入力を中断する
独自の stop_watch モジュールを作成しました。これにより、スレッドが作成され、数秒間スリープ状態になります。秒が経過すると、main.c でコールバック関数が呼び出され、ユーザーに時間が経過したことが通知されます。
これは、ユーザーが数字を入力するのに 3 秒しか与えられず、5 桁を入力する必要があるようにするためです。期限が切れた場合、プログラムは停止する必要があります。
2つの問題。1) 所要時間内に数字を入力した場合。スレッドをキャンセルするにはどうすればよいですか。thread_kill または thread_cancel を使用することを考えていましたか? 2) do_while ループで終了するにはどうすればよいですか? ユーザーが入力するのを待っている間、scanfはブロックします。
ご提案いただきありがとうございます。
以下の私のコード:
ちなみに、この質問はC99 gccに関するものです。
multithreading - より多くのスレッドを使用すると、プログラムの実行が遅くなる原因は何ですか?
この質問は、私が以前に尋ねたのと同じプログラムに関するものです。要約すると、次のようなループ構造を持つプログラムがあります。
bin_index
この質問の目的のために、共有状態を使用または変更しない、その引数の完全に決定論的な関数です。つまり、明らかに再入可能です。
私は最初、単一のスレッドを使用するためにこのプログラムを書きました。n
次に、スレッドが外側のループのすべての反復を実行するように、複数のスレッドを使用するように変換しましたi1 % nthreads == n
。したがって、各スレッドで実行される関数は次のようになります
すべてのthread_local_histogram
s は、最後にメインスレッドで合計されます。
奇妙なことに、ある特定のサイズの計算に対して 1 つのスレッドだけでプログラムを実行すると、約 6 秒かかります。2 つまたは 3 つのスレッドで実行し、まったく同じ計算を行うと、約 9 秒かかります。何故ですか?デュアルコア CPU を使用しているため、2 つのスレッドを使用する方が 1 つのスレッドよりも高速であると予想されます。プログラムはミューテックスやその他の同期プリミティブを使用しないため、2 つのスレッドを並行して実行できるはずです。
time
参考までに: 1 つのスレッドの典型的な出力(これは Linux 上にあります):
および 2 つのスレッド:
コードはhttp://static.ellipsix.net/ext-tmp/distintegral.ccsにあります。
PS まさにこの種のもののために設計されたライブラリがあり、おそらくパフォーマンスが向上する可能性があることは知っていますが、それが私の最後の質問でしたので、それらの提案をもう一度聞く必要はありません。(さらに、pthreads を学習体験として使用したかったのです。)
embedded - pthread_cancel は arm と ppc で異なる動作をしますか?
現在、arm および ppc アーキテクチャに展開されるマルチスレッド アプリケーションに取り組んでいます。アームの pthread_cancel に問題があります。
arm の pthread_cancel は、ppc と同じように動作しません。スレッドはキャンセルされますが、スレッドのローカル変数のデストラクタがアームで呼び出されていません。また、pthread_cleanup_push を介してインストールされたキャンセル クリーンアップ ハンドラ ルーチンを明示的に定義しようとしました。しかし、スレッドがキャンセルされたときに呼び出されていません。
コードは ppc で正常に動作します。スレッドがキャンセルされると、ローカル変数のデストラクタが呼び出されます。また、クリーンアップ ハンドラーを明示的に定義すると、pthread_cancel が呼び出されたときに呼び出されて実行されました。
何か不足していますか?おそらくいくつかのコンパイラオプション?
- プログラミング言語: C++
- コンパイラ: arm-linux-g++/powerpc-linux-g++
- OS: リナックス
編集:
私は、このlibc bugに記録された、一種の同様の問題を発見しました。
g++ の代わりに gcc を使用し、 -fno-exception コンパイラ オプションを追加するとうまくいきました。しかし、私は本当にこの問題の背後にあるものを理解したいと思っています. さらに、-fno-exception は、アプリケーションで例外処理を実行できないことを意味します。現在使用しているわけではありませんが、将来使用する可能性があります。
ありがとう。