
- •Clock_gettime
- •Int main(int argc, char **argv)
- •Timer_create
- •Int timer_create(
- •Timer_settime
- •Int timer_settime(
- •Int flags,
- •Многопотоковое программирование
- •13.1. Структура и методика использования потоков выполнения
- •13.2. Потоки и облегченные процессы
- •13.3. Api потоков выполнения фирмы Sun Microsystems
- •Void* printmsg (void* msg )
13.2. Потоки и облегченные процессы
Многопотоковые библиотечные функции, разработанные фирмой SUN Microsystems, создают облегченные процессы (lightweight processes, LWP), выполнение которых планируется ядром. Такие процессы похожи на виртуальные процессоры тем, что многопотоковые библиотечные функции упррав ляют выполнением потоков в процессе, связывая их с LWP. Если связанный с LWP поток приостанавливается (например, функцией thr_yield или thr_suspend), этот LWP можно связать с другим потоком, функцию которого он должен будет выполнять. Если LWP выполняет системный вызов от имени потока, он остается связанным с этим потоком до возврата из вызова. Если все LWP, связанные с потоками, заблокированы системными вызовами, многопотоковые библиотечные функции создают новые LWP, с которыми могут быть связаны потоки, ожидающие выполнения. Таким образом, обеспечивается непрерывность выполнения процесса. Наконец, если LWT больше чем потоков в процессе, то в целях экономии системных ресурсов многопотоковые библиотечные функции удаляют лишние LWP.
Большинство потоков не связаны, поэтому их можно связать с любыми свободными LWP. Вместе с тем процесс может создать один и более потоков, постоянно связанных с облегченными процессами. Эти потоки называются связанными потоками. Такое связывание потоков используется главным образом в тех случаях, когда потоки должны:
• планироваться ядром для обработки в режиме реального времени;
• иметь собственные альтернативные сигнальные стеки;
• иметь собственные будильники и таймер.
Взаимосвязь потоков, облегченных процессов и аппаратных процессоров показана на рис. 13.1.
На рис. 13.1 в процессе 123 есть два несвязанных потока, которые планируются на два LWP. В процессе 6231 — три несвязанных потока которые планируются на два LWP, и один связанный, который выполняется третьим LWP. В процессе 251 — четыре несвязанных потока которые планируются на один LWP. Несвязанные потоки в каждом процессе планируются многопотоковыми библиотечными функциями к связыванию с LWP и выполнению в этом процессе. LWP всех процессов, в свою очередь, планируются ядром к выполнению на трех имеющихся аппаратных процессорах.
В POSIX.lc у потоков есть атрибут, который называется областью действия конкуренции при планировании (scheduling contention scope). Если этот атрибут установлен в PTHREAD_SCOPE_PROCESS, то данным потоком управляют библиотечные функции пользовательского уровня, и он является "несвязанным". Все потоки с этим атрибутом совместно используют ресурсы процессора, доступные для содержащего их процесса. Если же вышеупомянутый атрибут установлен в PTHREAD_SCOPE_SYSTEM, то данным потоком управляет ядро операционной системы, и он считается "связанным". В стандарте POSIX.loc не указано, как ядро должно обрабатывать "связанный" поток
13.3. Api потоков выполнения фирмы Sun Microsystems
В этом разделе рассматриваются только API потоков выполнения, разработанные фирмой Sun Microsystems. API потоков выполнения стандарта POSIX.lc будут рассмотрены в разделе 13.4. Мы обсуждаем эти потоки выполнения отдельно, чтобы не запутать читателей. Прочитав раздел 13.4, вы узнаете о соответствии API Sun и POSIX.lc, благодаря которому многопотоковые приложения можно преобразовывать из формата Sun в стандарт POSIX.lc.
Чтобы
использоватьAPI
потоков выполнения фирмы Sun,
необходимо сделать следующее:
• включить в программу заголовок <thread.h>;
• откомпилировать и скомпоновать программу с опцией -lthread. Если указывается опция -lС, то опцию -lthread нужно поместить перед ней. Например, следующая команда компилирует многопотоковую C++-программу х. С:
% СС х.С -о х -Ithread -1C
Если не указано иного, то большинство описанных ниже API при успешном завершении возвращают 0, а в случае неудачи — -1. В последнем случае может вызываться функция perror, которая выводит сообщения ошибках.
#include <stdio.h>
#include <iostream.h>
#include <thread.h>
static mutex_t lockx; // define the lock storage