Современные операционные системы

Современные операционные системы
Процессы и потоки / Потоки в POSIX

Потоки в POSIX




Чтобы предоставить возможность создания переносимых многопоточных программ, в отношении потоков институтом IEEE был определен стандарт — IEEE standard 1003.1с. Определенный в нем пакет, касающийся потоков, называется Pthreads. Он поддерживается большинством UNIX-систем. В стандарте определено более 60 вызовов функций. Рассмотреть в этой книге такое количество функций мы не в состоянии. Лучше мы опишем ряд самых основных функций, чтобы дать вам представление о том, как они работают. В табл. 2.5 перечислены все вызовы функций, которые мы будет рассматривать.

Все потоки Pthreads имеют определенные свойства. У каждого потока есть свой идентификатор, набор регистров (включая счетчик команд) и набор атрибутов, которые сохраняются в определенной структуре. Атрибуты включают размер стека, параметры планирования и другие элементы, необходимые при использовании потока.

Новый поток создается с помощью вызова функции pthread_create. В качестве значения функции возвращается идентификатор только что созданного потока. Этот вызов намеренно сделан очень похожим на системный вызов fork, а идентификатор потока играет роль PID, главным образом для идентификации ссылок на потоки в других вызовах.

Когда поток заканчивает возложенную на него работу, он может быть завершен путем вызова функции pthread_exit. Этот вызов останавливает поток и освобождает пространство, занимавшееся его стеком.

Зачастую потоку необходимо перед продолжением выполнения ожидать окончания работы и выхода из другого потока. Ожидающий поток вызывает функцию pthread Join, чтобы ждать завершения другого указанного потока. В качестве параметра этой функции передается идентификатор потока, чьего завершения следует ожидать.

Иногда бывает так, что поток не является логически заблокированным, но считает, что он проработал достаточно долго, и намеревается дать шанс на выполнение другому потоку. Этой цели он может добиться за счет вызова функции pthread_yield. Для процессов подобных вызовов функций не существует, поскольку предполагается, что процессы сильно конкурируют друг с другом и каждый из них требует как можно больше времени центрального процессора. Но поскольку потоки одного процесса, как правило, пишутся одним и тем же программистом, то он добивается от них, чтобы они давали друг другу шанс на выполнение.



Полное описание: Потоки в POSIX




С этим описанием рассматриваются следующие темы:


Функция pthread _attr_init
Два следующих вызова функций, связанных с потоками, относятся к атрибутам. Функция pthread _attr_init создает структуру атрибутов, связанную с потоком, и инициализирует ее значениями по умолчанию. Эти значение (например, приоритет) могут быть изменены за счет работы с полями в структуре атрибутов. И наконец, функция pthread_attr_destroy удаляет структуру атрибутов, принадлежащую потоку, освобождая память, которую она занимала. На поток, который использовал эту структуру, влияние не оказывается, ... Читать

Вызов библиотечной процедуры
Когда поток завершает свою работу, выход из него может быть осуществлен за счет вызова библиотечной процедуры, к примеру thread_exit. После этого он прекращает свое существование и больше не фигурирует в работе планировщика. В некоторых использующих потоки системах какой-нибудь поток для осуществления выхода может ожидать выхода из какого-нибудь другого (указанного) потока после вызова процедуры, к примеру threadJoin. Эта процедура блокирует вызывающий поток до тех пор, пока не будет осуществлен ... Читать

Мьютексы в пакете pthreads
Пакет Pthreads предоставляет ряд функций, которые могут быть использованы для синхронизации потоков. Основным механизмом является использование переменных — мьютексов, предназначенных для защиты каждой критической области. Каждая такая переменная может быть в заблокированном или незаблокированном состоянии. Поток, которому необходимо войти в критическую область, сначала пытается заблокировать соответствующий мьютекс. Если мьютекс не заблокирован, поток может войти в нее беспрепятственно и заблок ... Читать

Код процедуры thread_yield
Но у потоков есть одно основное отличие от процессов. Когда поток на время останавливает свое выполнение, например когда он вызывает thread_yield, код процедуры thread_yield может самостоятельно сохранять информацию о потоке в таблице потоков. Более того, он может затем вызвать планировщик потоков, чтобы тот выбрал для выполнения другой поток. Процедура, которая сохраняет состояние потока, и планировщик, — это всего лишь локальные процедуры, поэтому их вызов намного более эффективен, чем осущест ... Читать

Превращение однопоточного кода в многопоточный
Многие существующие программы создавались под однопоточные процессы. Превратить их в многопоточные куда сложнее, чем может показаться на первый взгляд. Далее мы рассмотрим лишь некоторые из имеющихся подводных камней. Начнем с того, что код потока, как и код процесса, обычно содержит несколько процедур. У этих процедур могут быть локальные и глобальные переменные, а также параметры. Локальные переменные и параметры проблем не создают, проблемы возникают с теми переменными, которые носят глобальн ... Читать