2016-12-21 10 views
3

このanswer-pthreadが事前定義されたマクロため-lpthreadに好適であることを示唆する。-pthread、-lpthreadと最小動的リンク時の依存関係

経験上、-pthreadは私に一つだけの余分なマクロを提供します:#define _REENTRANT 1 、また、動的リンク時の依存関係としてlibpthread.so.0を強制的に表示されます。

-lpthreadでコンパイルすると、その依存関係は、実際にpthread関数のいずれかを呼び出す場合にのみ追加されます。その後、私は私のビルドスクリプトで異なるマルチスレッドプログラムを処理する必要がないので

これは、私にあることが好ましいです。

-pthread-lpthreadにはほかに何があるのですか?また、上記の動的リンク時の依存関係を強制しないで-pthreadを使用することは可能ですか?

デモンストレーション:

$ echo 'int main(){ return 0; }' | c gcc -include pthread.h -x c - -lpthread && ldd a.out | grep pthread 
$ echo 'int main(){ return pthread_self(); }' | c gcc -include pthread.h -x c - -lpthread && ldd a.out | grep pthread 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000003000c00000) 
$ echo 'int main(){ return 0; }' | c gcc -include pthread.h -x c - -pthread && ldd a.out | grep pthread 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000003000c00000) 
+2

実際にはpthreadを使用しないプログラムに対して、なぜ '-pthread'(または' -lpthread')を使用するのですか?あなたのプログラムが実際にpthreadを使用しているとしたら、どうして問題があるのでしょうか? –

+0

私が理解しておいてほしいのは、あなたがこれをしたいと思う唯一の理由は、決して良い考えではない*ユニバーサルビルドコマンド*を持つことです。つまり、実行可能ファイルがマルチスレッドであるかどうかです。 gccのスマートリンケージに頼る必要はありません。 –

+0

@JohnBollinger一般的なプロジェクトがビルドされています。 – PSkocik

答えて

7

あなたの代わりに-lpthread-pthread(つまり、glibcのに対して)、おそらくいくつかの十年半で古くなっGCCの特別なオプションを使用する必要がありますアイデア。現代のglibcでは、pthreadsライブラリがリンクされているかどうかに基づいて、スレッド化への切り替えは完全に動的です。 glibcのヘッダには何も_REENTRANTが定義されているかどうかに基づいてその動作を変更しません。動的切り替えの例として

FILE *ストリームを考えます。ストリーム上の特定の操作は、putcのようなロックです。シングルスレッドのプログラムをコンパイルしているかどうかにかかわらず、同じputc関数を呼び出します。それは、「pthreadの対応」putcにプリプロセッサによって再ルーティングされません。何が起こるかは、何もしないスタブ関数がロックとロック解除の動作を行うために使用されることです。スレッドライブラリがリンクされている場合、これらの機能は、実際のものに上書きされます。



私はglibcのインストールのインクルードファイルツリー全体をザッgrepをしました。 features.hでは、_REENTRANT__USE_REENTRANTが定義されます。次に、正確に1つのことは、__USE_REENTRANTが存在するかどうかに依存するように見えるが、それを可能にする並列条件を有する。すなわち、<unistd.h>にこれがあります:

#if defined __USE_REENTRANT || defined __USE_POSIX199506 
/* Return at most NAME_LEN characters of the login name of the user in NAME. 
    If it cannot be determined or some other error occurred, return the error 
    code. Otherwise return 0. 

    This function is a possible cancellation point and therefore not 
    marked with __THROW. */ 
extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1)); 
#endif 

これは怪しげに見えるし、廃止されています。私はglibc git repoのマスターブランチでそれを見つけることができません。

そして、ああ、見て単なる日前(12月6日)Aこのトピックで行われたコミット:変化の中で

https://sourceware.org/git/?p=glibc.git;a=commit;h=c03073774f915fe7841c2b551fe304544143470f

Make _REENTRANT and _THREAD_SAFE aliases for _POSIX_C_SOURCE=199506L. 

For many years, the only effect of these macros has been to make 
unistd.h declare getlogin_r. _POSIX_C_SOURCE >= 199506L also causes 
this function to be declared. However, people who don't carefully 
read all the headers might be confused into thinking they need to 
define _REENTRANT for any threaded code (as was indeed the case a long 
time ago). 

--- a/posix/unistd.h 
+++ b/posix/unistd.h 
@@ -849,7 +849,7 @@ extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) __THROW; 
    This function is a possible cancellation point and therefore not 
    marked with __THROW. */ 
extern char *getlogin (void); 
-#if defined __USE_REENTRANT || defined __USE_POSIX199506 
+#ifdef __USE_POSIX199506 
/* Return at most NAME_LEN characters of the login name of the user in NAME. 
    If it cannot be determined or some other error occurred, return the error 
    code. Otherwise return 0. 

を参照してください。 :)

+2

"-lpthreadの代わりにGCCの特別なオプション-pthreadを使うべきであるという考えは、おそらく10年半(glibcに関して)の時代遅れです。これは正しいですが、* glibcにのみ適用されます。他のプラットフォーム用にビルドした場合、 '-pthread'を使用しないで*簡単に問題になる可能性があるので、' -lpthread'の代わりに '-pthread'を使用することをお勧めします。後者は必ずしも必要ではない。 –

3

他の答えが-pthread(コンパイルおよびリンク時の両方で)は(のみリンク時に)-lpthreadと機能的に同等であることを説明Cライブラリは、GNU Cライブラリあります。しかし、これは世界で唯一のCライブラリではありません。

私は、POSIX準拠のオペレーティング・システムの現在世代のいずれかがスレッドアプリケーションのためのリンク時に-lpthread以上のものが必要ですが、コンパイルとリンク時の両方で-pthreadを使用している場合、あなたはATかどうかはわかりません古いアイロンを走らせようとする人にとって、少なくとも人生を楽にする。

は、あなたがスレッドを使用する必要はありませんプログラムにない使用-pthread(または-lpthread)を行う場合、古い鉄をも幸せになるだろう、と述べました。 "一般的なプロジェクトビルド"は良い考えではありません。

共有ライブラリが必要ないときに引き込まれる問題は、-Wl,--as-needed(GNU互換リンカーを使用)によって最もよく解決されます。これは下位互換性のためにデフォルトではオンになっていません。

関連する問題