Solarisスレッド(libthread)とPOSIXスレッド(libpthread)

Solaris10だとマルチスレッドアプリでも、libthreadもlibpthreadもリンクする必要ない!!の話題に少し関連。
Solarisには、Solarisスレッド(libthread)とPOSIXスレッド(libpthread)があって面倒くさいのよ。


ただ、thread_xxxをpthread_xxxをそれぞれに変換すればよいかというと、それぞれ過不足があって
そうは行かない。
なかなかたちが悪いのがfork()の動作が違うこと。
fork() と Solaris スレッドに関する問題

Solaris 10 リリースより前のリリースでは、Solaris スレッドと POSIX スレッドによる fork() の定義が異なっていました。
fork() の問題の詳細は、「プロセスの作成: exec と exit の問題」を参照してください。

Solaris libthread は、fork() と fork1() の両方をサポートしていました。
fork() 呼び出しには、「汎用 fork」セマンティクスがあります。
fork() は、スレッド、LWPを含めて、プロセス内のすべてを複製し、親の完全なクローンを生成しました。
一方、fork1() 呼び出しで作成されるクローンはスレッドを 1 つしかもちませんでした。
プロセスの状態とアドレス空間は複製されますが、スレッドについては呼び出しスレッドが複製されるだけでした。

POSIX libpthread は 、fork() のみをサポートしていました。
そのセマンティクスは、Solaris スレッドにおける fork1() と同じです。

fork() のセマンティクスが「汎用 fork」と「fork1」のどちらになるかは、
どちらのライブラリを使用するかで決まりました。-lthread を使ってリンクすれば、fork() に「汎用 fork」セマンティクスが
割り当てられます。-lpthread を使ってリンクすれば、fork() に「fork1」セマンティクスが割り当てられます。

Solaris 10 リリースから、Solaris スレッドと POSIX スレッドの fork() のセマンティクスが共通になりました。
つまり、 fork1() セマンティクスが呼び出し側だけを複製するようになりました。
すべてを複製するセマンティクスが必要なアプリケーションには、新しい関数 forkall () が提供されています。

昨日スレッドライブラリをリンクしなくも動作することはわかったが、fork()の違いがなくなるのはうれしいけど、
POSIX スレッドの fork()」がどう動くか、SolarisLinuxと含めると、僕の頭は混乱しそうだ。
はまらないためには、明示的にオプションつけることになるのかな。
マルチスレッドプログラムのコンパイルとリンク

Solaris 9 リリースでは、Solaris スレッドの API と pthread の API が別のライブラリ libthread と
libpthread に含まれています。Solaris 10 には、libc.so.1 に対するフィルタとして libthread.so と
libpthread.so の共有オブジェクトが実装されているため、Solaris 9 で別のライブラリを使用してコンパイルされた
アプリケーションでも動作するはずです。アプリケーションが明示的に libthread または libpthread ライブラリに
リンクされている場合は、Solaris 10 でコンパイルされたアプリケーションは Solaris 9 でも動作します。
-mt でリンクすると、アプリケーションを Solaris 9 で実行したとき、Solaris の fork() と fork1() の区別が保持されます。
-lpthread オプションでリンクすると、fork() は、Solaris 9 以前のリリースでの Solaris fork1() の呼び出しと同じ動作をします。

Solaris 9 リリースでは、アプリケーションが lthread または lpthread にリンクされていない場合、
-libthread と -libpthread のすべての呼び出しが無効です。実行時ライブラリ libc には、libthread と libpthread 内の
関数の仮エントリが NULL 手続きとして数多く定義されています。本当の手続きは、libc とスレッドライブラリ
(libthread または libpthread) の両方がアプリケーションにリンクされたときに、そのスレッドライブラリによって挿入されます。

Solaris 9 以降のリリースでは、スレッドを使用しないプログラムをリンクするときに、-mt、-lthread または -lpthread を
指定しても、意味上の違いは発生しません。余分なスレッドや LWP が生成されることはありません。
メインスレッド (唯一のスレッド) が、従来のシングルスレッドプロセスとして実行されます。
プログラムへの唯一の影響は、システムライブラリのロックが空の関数の呼び出しではなく本当のロックになる点です。
競合しないロックを獲得する必要があります。

POSIX スレッド環境でのコンパイル