2

スレッド内の構造へのポインタがあり、それをパイプ経由で親プロセスに渡したいとします。


例:

MyType * someType; 

次に、キャストsomeTypevoid *てパイプに配置します。どうすればそれができますか?

4

4 に答える 4

13

親プロセスへのポインターを物理的に渡すことはできますが、その値はプロセスにとって意味がなく、最良のシナリオは即時のクラッシュです。ポインターは、メモリ内のオブジェクトのアドレスを示します。このアドレスは、子プロセスのコンテキストでのみ有効であり、親プロセス内のまったく異なるオブジェクトを指します。

このシナリオを有効にするには、次のいずれかを実行する必要があります

  • オブジェクト全体を、シリアル化されたものでパイプを介して渡します
  • プロセス間の共有メモリ ベースに相対的なポインターを渡し、親プロセスで適切な修正を行います。

編集

私の答えは、質問が子プロセスと親プロセスの間でポインターを渡す方法について尋ねていたときに書かれたことに注意してください。その後、スレッドに更新されました。

于 2009-06-09T18:47:18.457 に答える
4

もう 1 つのオプションは、オブジェクトを共有メモリに格納してから、セグメント ID を親プロセスに渡すことです。

その後、親はメモリにアタッチし、オブジェクトにアクセス/変更できます。

これはいくつかの背景を提供します: http://fscked.org/writings/SHM/shm.html

于 2009-06-09T18:56:05.990 に答える
2

これとあなたが引用した他の質問の行の間を読むと、「親プロセス」を使用してメインプロセススレッドを参照し、「スレッド」を使用して同じプロセス内で作成された新しいスレッドを参照しています。これは、問題についてのあなたの考えと、質問に答えようとしている他の人の両方に混乱を引き起こしています.

このシナリオでは、プロセスは 1 つだけで、2 つのスレッドがあります。OS がプロセスを開始したときに、最初のスレッドが作成されました。2 つ目は、1 つ目によって意図的に作成されました。これらのスレッド間の通信にパイプを使用することにしました。

まず、パイプはプロセス間通信を処理するように設計されているため、スレッド間通信に対する少し重いソリューションであるという他の質問に対する多くの回答に同意します。そうは言っても、彼らはうまくいくでしょう。

次に、プロセス間でポインターを意味のある形で移動できないことに注意してください。ポインターは、単一のプロセス内でのみ有効です。共有メモリ領域は各プロセスで異なる仮想アドレスにマップされる可能性があるため、共有メモリへのポインタにも問題があります。パイプの両端が同じプロセスにあるように見えるので、これは問題ではありませんが、そうでない場合は大きな問題になります。

これらすべてを念頭に置いて、ポインターの表現について自分自身に同意する必要があります。最も簡単な答えは、sizeof(void *)バイトをパイプに書き込むことです。読み出されたら、それらのバイトをポインター変数に戻し、実際の型にキャストし直します。もちろん、周囲のプロトコルはそのタイプが何であるかを知っている必要があります。

2 つのスレッドを別々のプロセスに存在させたり、このコードを再利用して進行中の作業をファイルに保持 (チェックポイント) したりする場合は、より複雑な問題が発生します。データと状態の永続性、ピクル、マーシャリングに関する議論を検索すると、考えるべきことがわかります。

于 2009-06-09T20:55:51.910 に答える
1

共有メモリに配置し、共有メモリ ベースに相対的なポインタを渡します。ポインターのキャストは、コンパイラーがオブジェクトを整列する方法によって異なります。相対ポインター位置を取得するときの覚えておいてください。ポインター演算は、指している物のサイズに基づいています。

于 2009-06-09T20:32:34.830 に答える