Почему библиотека glibc и pthread определили одни и те же API?

Почему в библиотеке glibc и pthread определены оба API? Вот снимок

[email protected]:/lib$ objdump -T /lib/i386-linux-gnu/libc.so.6 |grep pthread_cond_signal
000f8360 g    DF .text  00000039  GLIBC_2.3.2 pthread_cond_signal
0012b940 g    DF .text  00000039 (GLIBC_2.0)  pthread_cond_signal

[email protected]:/lib$ objdump -T /lib/i386-linux-gnu/libpthread.so.0 |grep pthread_cond_signal
0000b350 g    DF .text  0000007c (GLIBC_2.0)  pthread_cond_signal
0000af90 g    DF .text  000000fc  GLIBC_2.3.2 pthread_cond_signal

Ответ 1

libpthread.so также является частью glibc, и оба они содержат (идентичные) определения некоторых символов.

Если вы ищете pthread_create вместо этого, вы увидите, что он присутствует только в libpthread.so - это означает, что программы должны ссылаться на libpthread.so для фактического создания потоков , но могут использовать мьютексы и переменные условия в однопоточные программы, которые ссылаются только на libc.so. Это полезно для межпроцессных мьютексов и переменных процесса interprocess, которые живут в общей памяти и используются для синхронизации с отдельными процессами. (исправления благодаря комментарию Zan Lynx ниже).

Не стоит связываться с libpthread.so и libc.so, хотя оба они определяют символ. Линейки ELF позволяют нескольким разделяемым библиотекам содержать определения одного и того же символа, и компоновщик будет выбирать первый, который он видит, и использовать его для всех ссылок на этот символ, это называется символьная интерпозиция. Еще одна функция, которая позволяет определить несколько символов, - это если одна библиотека содержит слабые символы, которые будут перекрыты несимметричными символами с тем же именем. В этом случае определения в две библиотеки идентичны, поэтому не имеет значения, что используется libpthread.so переопределить те, что указаны в libc.so. Если вы используете LD_DEBUG и измените порядок аргументов на компоновщик, вы сможете увидеть, в какой библиотеке находится символ.

Как и две библиотеки, определяющие один и тот же символ, каждая библиотека имеет два определения символа с разными версиями символов GLIBC_2.0 и GLIBC_2.3.2. Это управление версиями символов позволяет нескольким определениям сосуществовать в одной и той же библиотеке, чтобы новые, улучшенные версии функции были добавлены в библиотеку без нарушения кода, связанного со старой реализацией. Это позволяет использовать одну и ту же разделяемую библиотеку для приложений с использованием LinuxThreads и приложений с использованием NPTL. Символ по умолчанию, с которым привязка ссылается при ссылке на библиотеку, будет [email protected]_2.3.2, которая соответствует NPTL реализации этой функции (NPTL был сначала включен в glibc 2.3.2). Старшим символом [email protected]_2.0 является старая реализация LinuxThreads, которая была по умолчанию до предоставления NPTL. Приложения, связанные со старыми (до 2.3.2) версиями glibc, будут привязаны к [email protected]_2.0 и будут использовать этот символ.