カーネルソースコード:do_fork()のparent_tidptrとchild_tidptrは何ですか?

カーネルソースコード:do_fork()のparent_tidptrとchild_tidptrは何ですか?

上記の内容については協会parent_tidptr新しいプロセスを作成するとはどういう意味ですかchild_tidptrdo_fork()

ベストアンサー1

まず、rawシステムコールインターフェイスを見てみましょう。アーキテクチャによって少しずつ異なりますが、x86-64では次のようになります。

   long clone(unsigned long flags, void *child_stack,
              int *ptid, int *ctid,
              unsigned long newtls);

ptidctidあなたのものであり。今何を見てみましょうparent_tidptrchild_tidptrclone(2)マニュアルページは次のように言うべきです:

   CLONE_CHILD_CLEARTID (since Linux 2.5.49)
          Erase  the  child  thread  ID  at the location ctid in
          child memory when the child exits, and do a wakeup  on
          the  futex  at that address.

   CLONE_CHILD_SETTID (since Linux 2.5.49)
          Store  the child thread ID at the location ctid in the
          child's memory.

   CLONE_PARENT_SETTID (since Linux 2.5.49)
          Store  the child thread ID at the location ptid in the
          parent's memory. 

これらのフラグは主にスレッドライブラリの実装用に設計されています。 NPTLの実装を見るとpthread_create()glibcの中でついにコードを見つけました。sysdeps/unix/sysv/linux/createthread.cclone()CLONE_PARENT_SETTIDCLONE_CHILD_CLEARTIDを含む電話をかけますflags

その呼び出しでおよびパラメータもclone()表示できます。ptidctid同じ住所を指す。 (POSIXスレッドはアドレス空間を共有していることに注意してください。これはフラグによって行われますclone() CLONE_VM。)

さて、ここで何が起こっているのか見てみましょう。

  • CLONE_PARENT_SETTIDカーネルスレッドIDがユーザー空間のどこかに保存されているかどうかを確認するために使用されます。スレッド実装のユーザースペース側では、このスレッドIDを知る必要があります。
  • CLONE_CHILD_CLEARTIDTerminatesによって生成されたスレッドは、同じ場所をクリア(つまりゼロ化)するために使用されますclone()

さらに一歩進みましょう...

ptid転送/返されたスレッドIDctidは次のとおりです。いいえPOSIXスレッドID()と同じですpthread_tが、NPTLなどの1:1スレッド実装では、カーネルスレッドIDとPOSIXスレッドIDは1対1で対応します。カーネルスレッドIDはLinuxを使用するのと同じです。gettid()呼ぶこれもclone()システムコールの戻り値として返されます。これは次の質問を提示します。なぜptid/が必要ですかctid?問題は、ユーザー空間の観点から状況が次のようになることです。

tid = clone(...);

tidユーザー空間スレッド実装の観点から見ると、ここには競争があります。後ろに clone()返品。これは、新しいスレッドがタスク(シャットダウンなど)を実行する前にユーザースペーススレッドライブラリにこの情報が必要な場合に問題が発生する可能性があることを意味します。CLONE_PARENT_SETTID新しいスレッドIDが指す位置に配置されていることを確認するために使用されます。ptid 今後 clone()スレッドライブラリがこれらの競合状態を回避できるように返します。 (CLONE_CHILD_SETTID同様の効果で使用することもできます。)

CLONE_CHILD_CLEARTIDClear ptid/を使用する理由ctidは方法を提供するためです。pthread_join()別のスレッドを呼び出すと、そのスレッドが終了したことがわかります。デフォルトでは、ptid/ ctidlocation は次のように使用されます。ピューテックス、しかもfutex()システムコールは、その位置の整数が変更されるのを待ってブロックするために使用されます。 (詳細は少し複雑ですが、grepglibcソースコードで中和を使用するためのものです。最終的には操作が発生します。上記の宛先アドレスからfutex wakeupを覚えてください。)lll_wait_tidlll_futex_waitFUTEX_WAITCLONE_CHILD_CLEARTID

おすすめ記事