14

2 つのスレッドを並行して実行するコードを書いています。

1st は、2 番目のスレッドを開始したメイン スレッドです。2 番目のスレッドは、空の while ループを実行する単純なスレッドです。

今、私はそれを作成した最初のスレッドによって2番目のスレッドの実行を一時停止/中断したいと考えています。そしてしばらくして、一時停止/中断された場所から(コマンドまたは関数を発行して)2番目のスレッドの実行を再開したいと思います。

4

9 に答える 9

17

この質問はミューテックスの使い方ではなく、スレッドを中断する方法に関するものです。

Unix の仕様には pthread_suspend と呼ばれるスレッド関数と pthread_resume_np と呼ばれるスレッド関数がありますが、Linux、FreeBSD、NetBSD などを作成している人々は、何らかの理由でこれらの関数を実装していません。

それを理解するために、機能は単にそこにありません。回避策はありますが、残念ながら Windows で SuspendThread を呼び出すのと同じではありません。スレッドを停止してシグナルの使用を開始するには、あらゆる種類の移植性のないことを行う必要があります。

スレッドの停止と再開は、デバッガーとガベージ コレクターにとって不可欠です。たとえば、「SuspendThread」関数を適切に実装できないバージョンの Wine を見たことがあります。したがって、それを使用する Windows プログラムは正しく動作しません。

JVM がガベージ コレクターにシグナルのこの手法を使用しているという事実に基づいて、シグナルを使用して適切にそれを行うことが可能であると考えましたが、人々が JVM でデッドロックなどに気付いているという記事をオンラインで見たばかりです。再現不可能。

そのため、質問に答えるために、pthread_suspend_np を実装した優れた Unix を使用しない限り、Unix でスレッドを適切に一時停止および再開することはできません。それ以外の場合は、信号で立ち往生しています。

シグナルの大きな問題は、約 5 つの異なるライブラリがすべて同じプログラムにリンクされていて、すべてが同じシグナルを同時に使用しようとしている場合です。このため、ValGrind のようなものや、たとえば Boehm GC を 1 つのプログラムで実際に使用することはできないと思います。少なくとも、ユーザー空間の最下位レベルでの主要なコーディングはありません。

この質問に対する別の答えが考えられます。Linuz Torvalds が NVidia に対して行っていることを実行し、指を弾いて Linux に欠けている 2 つの最も重要な部分を実装してもらいます。1 つ目は pthread_suspend で、2 つ目は適切なガベージ コレクターを実装できるように、メモリ ページのダーティ ビットです。オンラインで大規模な請願を開始し、その指を弾き続けます。おそらく、Windows 20 が登場する頃には、スレッドの一時停止と再開、およびダーティ ビットの存在が、Windows と Mac が Linux や、pthread_suspend とダーティ ビットを実装していない Unix よりも優れている根本的な理由の 1 つであることに気付くでしょう。 VirtualAlloc が Windows で行うように、仮想ページで。

私は希望に生きていません。実際、私は何年もかけて Linux 向けのビルドに関する将来の計画を立てていましたが、信頼できるものはすべて、仮想メモリのダーティ ビットの可用性と、スレッドをクリーンにサスペンドできるかどうかにかかっているように思われるため、希望を捨てました。

于 2012-11-15T14:29:50.003 に答える
4

私の知る限り、pthreads を使用して他のスレッドを一時停止することはできません。条件変数のようなものを使用して、一時停止する必要がある時間をチェックする 2 番目のスレッドに何かが必要です。これは、この種のことを行う標準的な方法です。

于 2012-07-13T10:13:33.137 に答える
2

POSIX には pthread_suspend()、pthread_resume() のような API はありません。
ほとんどの条件変数は、他のスレッドの実行を制御するために使用できます。

条件変数メカニズムにより、スレッドは実行を一時停止し、何らかの条件が真になるまでプロセッサを解放できます。条件変数は常にミューテックスに関連付ける必要があります。これは、待機の準備をしている 1 つのスレッドと、最初のスレッドが実際に待機する前に別のスレッドが条件を通知してデッドロックを引き起こす可能性がある競合状態を回避するためです。

詳細については

Pスレッド

Linux チュートリアル Posix スレッド

于 2012-07-13T10:36:56.420 に答える
1

代わりにプロセスを使用できる場合は、ジョブ制御シグナル (SIGSTOP / SIGCONT) を 2 番目のプロセスに送信できます。これらのプロセス間でメモリを共有したい場合は、SysV 共有メモリ (shmop、shmget、shmctl...) を使用できます。

自分で試したことはありませんが、下位レベルの clone() システムコールを使用して、シグナルを共有しないスレッドを生成できる可能性があります。これで、SIGSTOP と SIGCONT を別のスレッドに送信できる可能性があります。

于 2012-07-13T10:58:05.977 に答える
0

あなたが私の答えを気に入るかどうかはわかりません。しかし、この方法でそれを達成できます。

それがスレッドではなく別のプロセスである場合、信号を使用して解決策があります(これはスレッドでも機能する可能性があります。誰かがあなたの考えを共有できるかもしれません)。

現在、プロセスの実行を一時停止または再開するシステムはありません。しかし、確かにあなたはそれを構築することができます。

プロジェクトでそれが必要な場合に行う手順:

  • 2 番目のプロセスのシグナル ハンドラーを登録します。
  • シグナル ハンドラ内で、セマフォを待ちます。
  • 他のプロセスを一時停止したいときはいつでも、他
    のプロセスを登録したシグナルを送信するだけです。プログラムはスリープ状態になります。
  • プロセスを再開したい場合は、別のシグナルを再度送信できます。そのシグナルハンドラ内で、セマフォがロックされているかどうかを確認します。ロックされている場合は、セマフォを解放します。したがって
    、プロセス 2 は実行を継続します。

これを実装できる場合は、うまくいったかどうかにかかわらず、フィードバックを共有してください。ありがとう。

于 2012-07-13T11:27:40.277 に答える
0

スレッドに一時停止を実装するには、何らかのイベントが発生するまでスレッドを待機させる必要があります。スピンロック ミューテックスの待機は、CPU サイクルの浪費です。CPUサイクルが他のプロセス/スレッドによって使い果たされた可能性があるため、この方法に従うべきではありません。非ブロッキング記述子 (パイプ、ソケット、またはその他) を待ちます。スレッド間通信にパイプを使用するサンプル コードここで見ることができます 上記のソリューションは、2 番目のスレッドが一時停止と再開のシグナルだけでなく、複数のソースからより多くの情報を持っている場合に役立ちます。トップレベルの select/poll/epoll は、ノンブロッキング記述子で使用できます。select/poll/epoll システム コールの待機時間を指定することができ、そのマイクロ秒に相当する CPU サイクルだけが無駄になります。2 番目のスレッドには、単に一時停止して再開するだけでなく、より多くのことやイベントを処理するという前向きな考えで、このソリューションについて言及します。質問した内容より詳細でしたら申し訳ありません。

もう 1 つの簡単な方法は、これらのスレッド間でブール変数を共有することです。メイン スレッドは変数のライターであり、0 は停止を意味します。1 - 再開を意味します。2 番目のスレッドは、変数の値のみを読み取ります。「0」状態を実装するには、usleep を sime マイクロ秒使用してから、再度値を確認します。設計で数マイクロ秒の遅延が許容されると仮定します。「1」を実装するには、一定数の操作を行った後に変数の値を確認します。それ以外の場合は、'1' から '0' 状態に移行する信号を実装することもできます。

于 2012-07-14T19:05:21.523 に答える
0

ミューテックスを使用してそれを行うことができます。擬似コードは次のようになります。

While (true) {
    /* pause resume */
    lock(my_lock); /* if this is locked by thread1, thread2 will wait until thread1 */
                   /* unlocks it */
    unlock(my_lock); /* unlock so that next iteration thread2 could lock */

    /* do actual work here */
}
于 2012-07-13T10:13:37.310 に答える