• В ядрах версии ниже 2.6.16 альтернативный стек сигналов относился к отдельным потокам, однако новый поток ошибочно наследовал его атрибуты (которые устанавливаются с помощью вызова sigaltstack()) от своего создателя, вызвавшего pthread_create(); в результате оба потока имели общий альтернативный стек сигналов.

• В ядрах версии ниже 2.6.16 только лидирующий (то есть главный) поток мог начать новую сессию с помощью вызова setsid().

• В ядрах версии ниже 2.6.16 только лидирующий поток мог использовать setpgid(), чтобы сделать свой процесс лидером в группе.

• В ядрах версии ниже 2.6.12 интервальные таймеры, созданные с помощью вызова setitimer(), не разделялись между потоками процесса.

• В ядрах версии ниже 2.6.10 потоки процесса не разделяли параметры ограничения ресурсов.

• В ядрах версии ниже 2.6.9 процессорное время и сведения о потреблении ресурсов, возвращаемые вызовами times() и getrusage() соответственно, относились к отдельным потокам.

Библиотека NPTL проектировалась так, чтобы быть совместимой с LinuxThreads на уровне двоичного интерфейса (Application Binary Interface, ABI). Это означает, что программы, скомпонованные с библиотекой GNU C, которая поддерживала LinuxThreads, не нужно заново компоновать для использования NPTL. Однако с переходом на NPTL поведение программы может измениться — в основном из-за более строгого соблюдения спецификации Pthreads из стандарта SUSv3.

33.5.3. Выбор между разными реализациями многопоточности

Некоторые дистрибутивы Linux поставляются вместе с библиотекой GNU C, которая предоставляет как LinuxThreads, так и NPTL; реализация по умолчанию определяется динамическим компоновщиком в соответствии с текущим ядром системы (такие дистрибутивы уже устарели, потому что glibc, начиная с версии 2.4, больше не предоставляет LinuxThreads). Следовательно, у нас может возникнуть необходимость ответить на следующие вопросы.

• Какая реализация многопоточности доступна в текущем дистрибутиве Linux?

• Какая реализация используется по умолчанию и каким образом нам самим выбрать подходящую библиотеку для нашей программы, если дистрибутив предоставляет как LinuxThreads, так и NPTL?

Определение доступной реализации многопоточности

Мы можем воспользоваться несколькими методиками для обнаружения доступной реализации многопоточности или, если их сразу две, реализации, которая используется по умолчанию при запуске программы.

В системе с glibc версии 2.3.2 и выше это можно сделать с помощью следующей команды:

$ getconf GNU_LIBPTHREAD_VERSION

Если библиотека NPTL является единственной реализацией в системе или используется по умолчанию, мы получим следующую строку в качестве результата:

NPTL 2.3.4

Начиная с glibc 2.3.2, программа может получить похожие сведения с помощью функции confstr(3), которая возвращает значение переменной _CS_GNU_LIBPTHREAD_VERSION (устанавливаемое самой библиотекой glibc).

В системах с более ранними версиями библиотек GNU C необходимо проделать немного дополнительной работы. Во-первых, с помощью следующей команды можно узнать путь к библиотеке GNU C, который использовался при запуске программы (здесь в качестве примера мы взяли стандартную команду ls, полный путь к которой — /bin/ls):

$ ldd /bin/ls | grep libc.so

libc.so.6 => /lib/tls/libc.so.6 (0x40050000)

Чуть больше о программе ldd (list dynamic dependencies — «список динамических зависимостей») можно узнать в разделе 41.5.

Путь к библиотеке GNU C указан после =>. Если выполнить его в качестве команды, glibc сама выведет целый набор информации. Мы можем отфильтровать полученные сведения с помощью команды egrep, чтобы выбрать строки с данными о реализации многопоточности:

$ /lib/tls/libc.so.6 | egrep — i 'threads|nptl'

Native POSIX Threads Library by Ulrich Drepper et al

Мы указали для команды egrep регулярное выражение nptl, поскольку некоторые версии glibc, поддерживающие NPTL, выводят информацию следующего вида:

NPTL 0.61 by Ulrich Drepper

Поскольку путь к библиотеке glibc может варьироваться в зависимости от дистрибутива, мы можем воспользоваться консольной командой, которая точно так же выведет сведения о текущей реализации многопоточности в любой Linux-системе:

$ $(ldd /bin/ls | grep libc.so | awk '{print $3}') | egrep — i 'threads|nptl'

Native POSIX Threads Library by Ulrich Drepper et al

Выбор реализации многопоточности, которая будет использоваться в программе

Перейти на страницу:

Похожие книги