フォーク後にデッドスレッドを再作成する

ご存じのように、アプリケーション内のすべてのスレッドは、フォークを実行しているスレッド以外のforkしたプロセスで停止します。しかし、私は、 pthread_create を呼び出し、 pthread_attr_setstack を使用して、新しく作成されたスレッドにデッドスレッドと同じスタックを割り当てるように、フォークされたプロセスでそれらのスレッドを再確立する予定です。次のようなもの。

// stackAddr and stacksize taken from the dead thread    
pthread_attr_setstack(&attr, stackAddr, stacksize);
rc = pthread_create(&thread, &attr, threadRoutine, NULL); 

しかし、私はまだ同じポイントからスレッドを再起動するために、スタックポインタ、ベースポインタ、命令ポインタなどのCPUレジスタ値を取得する必要があります。どうやってやるの?私の目標を達成するために他に何が必要ですか?

また、私は64ビットアーキテクチャを使用しています。 32ビットのものと比較して、それにはどんな追加の困難がありますか?

7
pthread_atfork を見ましたか?私はmutexes、condvarsなどが、そのような種類の施設で壊れてしまうのを避ける方法を見ません。彼らと一緒にさえ、これはかなり毛深くて壊れやすいようです。
追加された 著者 Duck,
ミックススレッドとフォークコールが悪い考えであると読んだと思っていました。フォークの後でスレッドを復活させる(私は思う)、まったく新しいレベルに悪いアイデアを取ります。それが可能かどうかわかりませんが、たとえそうであってもそれは良いアイデアだとは思っていません。あなたが本当にやりたいことをやるより良い方法があると確信しています。
追加された 著者 Kevin,
私は彼がLinuxにsolarisアプリケーションを移植しようとしていると思う。 Solarisはフォークコールを持っているので、おそらく彼はそれに依存しているアーキテクチャを考え出しています。
追加された 著者 Kevin,
@denniston:多分あなたはここでちょっとした助けができます:)
追加された 著者 MetallicPriest,
@ denniston.t、チェックポイント!
追加された 著者 MetallicPriest,
「知っているように、アプリケーション内のすべてのスレッドが分岐したプロセスで死ぬ」 - それはそうですか?私の知る限り、 pthread_createcloneCLONE_VM | CLONE_THREAD | CLONE_SIGHAND などのフラグの組み合わせでのみ)を呼び出すだけで、一方、 fork は、フラグを指定せずに clone を呼び出し、「すべてを分けて」別のプロセスを作成しますが、既存のプロセス(つまり、5つのスレッドフォークを持つプロセスには5つのスレッドプロセスがあり、別のプロセスがあります)。
追加された 著者 Damon,
ちょうど32ビットとして64ビットでは難しい。
追加された 著者 David Heffernan,
明確にするために、EXIT_DEADまたはEXIT_ZOMBIEとしてフラグが立てられたプロセスについて説明します。私はEXIT_ZOMBIEを想定しています.EXIT_DEADではこれが可能ではないはずです。
追加された 著者 gnometorule,
@MetallicPriest私はそれを知っていた!私の研究の大部分はアプリケーションチェックポイントです。ちょうど私の疑惑を確認する:-)。ありがとう。
追加された 著者 proc-self-maps,
これは珍しい仕事のようです。これを行うための少しの動機付けで私たちに啓発してもらえますか?私はあなたがあなたのデザインを放棄すべきではないと言っていますが、私はこの機能のユースケースが何であるか非常に興味があります。
追加された 著者 proc-self-maps,

3 答え

私は足に自分自身を撃って髪を失う2つの可能な方法を見ています^ W ^ W ^ W ^ W ^ W ^ W ^

  • 各スレッドを fork()の前に getcontext()を呼び出すように強制してから、 setcontext()コード>。おそらく動作しませんが、あなたは楽しみにしてみることができます。
  • ptrace(PTRACE_GETREGS)ptrace(PTRACE_GETFPREGS)
3
追加された
getcontext/setcontextを実行する代わりに、私はsetjmp/longjmpを使用しますか?私はそれをやろうと考えていた。
追加された 著者 MetallicPriest,
@ MetallicPriest:おそらく、私が setcontext()で言ったように、私はそのアプローチではあまり期待していません。
追加された 著者 ninjalj,
以下も参照してください: lwn.net/Articles/463148
追加された 著者 ninjalj,

現在のプロセス内の他のスレッドは、フォークによって殺されません。それらはまだそこにあり、親プロセスで実行されています。現在のプロセスでは、 fork は1つのスレッドのみをフォークし、親プロセス内のすべての非スレッドリソースのコピーを持つ1つのスレッドを実行する新しいプロセスを作成するという問題があります。

あなたが望むのは、マルチスレッド・タスク全体を複製し、その中のすべてのスレッドをフォークし、同じ数のスレッドで新しいプロセス/タスクを作成する方法です。

THATを実行するには、プロセス内の他のスレッドをすべて見つけて一時停止し、現在の状態(保持しているすべてのロックを含む)をダンプし、新しいプロセスをforkしてから、その子は、必要に応じて新しい子スレッドを参照するためにロック状態を再配線します。

残念なことに、POSIXのpthreadインタフェースは絶望的に指定されておらず、その方法を提供していません。特に、実際に実行されているスレッドを把握できるように、あらゆる種類のリフレクションインターフェイスが欠けています。

とにかくこれをやりたければ、私はこれにアプローチしようとする2つの方法を見ることができます:

  • /proc/self/taskを突き止めて、プロセス内でどのスレッドが実行されているかを把握し、おそらく、内部状態を取得するために他のスレッドをptrace(2)する必要があります。これは非常に難しいでしょう。

  • pthreadsライブラリをラップする - ライブラリを直接使うのではなく、すべての呼び出しを傍受し、作成されるすべてのスレッド/ mutexes/locksを追跡して、フォークするときにその情報を利用できるようにする。これは、pthreadsを使用するサードパーティのライブラリを使用したくない限り、うまく動作します。

2番目のオプションははるかに簡単で(やや移植性がありますが)、アプリケーション全体のすべてのソースコードにアクセスできる場合にのみうまく動作し、ラッパーを適切に使用するように変更できます。

2
追加された
私は上記のアプローチをsetjmp/longjmpと組み合わせます。バリアポイントのように、ロックが保持されていないときに私がフォークすると仮定してください。それは可能ではないでしょうか?それは私のように見えます。
追加された 著者 MetallicPriest,
ある男性の「絶望的に不特定」は、別の「きれいに抽象化された」ものである。ロックの内部のようなものを指定しないと、実装者は自分たちの環境にとって最良の方法で物事を自由に行うことができます。
追加された 著者 caf,
@caf:適切な仕様では、プログラムの管理を可能にする方法でロックの動作のようなものを指定することができますが、実装者が自分の環境に最も適した方法を自由に実行できるようにします。
追加された 著者 Chris Dodd,
@MatallicPriest - スレッドを休止して(ロックを保持していないところまで動かして一時停止させる)方法があれば、それを使ってロック管理の問題を解決することができます。
追加された 著者 Chris Dodd,

周りにグーグルで行くと、私はソラリスがあなたが望むものとまったく同じforkall()呼び出しを持っていることを発見しました。

http://download.oracle.com /docs/cd/E19963-01/html/821-1601/gen-1.html

私はあなたがLinux上で動作していると仮定していますが、x86ハードウェア上でsolarisを実行することは可能です。だから多分それはあなたのためのオプションです。

0
追加された
ああ、ha ...あなたはおそらくsolarisプログラムをlinuxに移植しています。
追加された 著者 Kevin,
はい、知っています、私はすでに自分のプログラムで使っていましたが、今はLinuxでやりたいと思っています。
追加された 著者 MetallicPriest,