Спонсор: Microsoft
Опубликован: 13.11.2010 | Уровень: для всех | Доступ: платный | ВУЗ: Санкт-Петербургский государственный университет
Лекция 10:

Потоки (threads) и многопоточное выполнение программ (multi-threading)

< Лекция 9 || Лекция 10: 1234 || Лекция 11 >

Потоки POSIX (Pthreads)

В качестве конкретной модели многопоточности рассмотрим потоки POSIX (напомним, что данная аббревиатура расшифровывается как Portable Operating Systems Interface of uniX kind – стандарты для переносимых ОС типа UNIX). Многопоточность в POSIX специфицирована стандартом IEEE 1003.1c, который описывает API для создания и синхронизации потоков. Отметим, что POSIX-стандарт API определяет лишь требуемое поведение библиотеки потоков. Реализация потоков оставляется на усмотрение авторов конкретной POSIX-совместимой библиотеки. POSIX-потоки распространены в ОС типа UNIX, а также поддержаны, с целью совместимости программ, во многих других ОС, например, Solaris и Windows NT.

Стандарт POSIX определяет два основных типа данных для потоков: pthread_t – дескриптор потока ; pthread_attr_t – набор атрибутов потока.

Стандарт POSIX специфицирует следующий набор функций для управления потоками:

  • pthread_create(): создание потока
  • pthread_exit():завершение потока (должна вызываться функцией потока при завершении)
  • pthread_cancel():отмена потока
  • pthread_join():заблокировать выполнение потока до прекращения другого потока, указанного в вызове функции
  • pthread_detach():освободить ресурсы занимаемые потоком (если поток выполняется, то освобождение ресурсов произойдёт после его завершения)
  • pthread_attr_init():инициализировать структуру атрибутов потока
  • pthread_attr_setdetachstate():указать системе, что после завершения потока она может автоматически освободить ресурсы, занимаемые потоком
  • pthread_attr_destroy():освободить память от структуры атрибутов потока (уничтожить дескриптор).

Имеются следующие примитивы синхронизации POSIX-потоков с помощью мьютексов (mutexes) – аналогов семафоров – и условных переменных (conditional variables) – оба эти типа объектов для синхронизации подробно рассмотрены позже в данном курсе:

  • - pthread_mutex_init() – создание мьютекса;
  • - pthread_mutex_destroy() – уничтожение мьютекса;
  • - pthread_mutex_lock() – закрытие мьютекса;
  • - pthread_mutex_trylock() – пробное закрытие мьютекса (если он уже закрыт, вызов игнорируется, и поток не блокируется);
  • - pthread_mutex_unlock() – открытие мьютекса;
  • - pthread_cond_init() – создание условной переменной;
  • - pthread_cond_signal() – разблокировка условной переменной;
  • - pthread_cond_wait() – ожидание по условной переменной.

Рассмотрим пример использования POSIX-потоков на языке Си.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <pthread.h> 
static void wait_thread(void) 
{ 
 time_t start_time = time(NULL); 
 while (time(NULL) == start_time) 
 { 
 // никаких действий, кроме занятия процессора на время до 1 с. 
 } 
} 
 
static void *thread_func(void *vptr_args) 
{ int i; 
 for (i = 0; i < 20; i++) { 
 fputs(" b\n", stderr); 
 wait_thread(); 
 } 
 return NULL; 
} 
int main(void) 
{ int i; 
 pthread_t thread; 
 if (pthread_create(&thread, NULL, thread_func, NULL) != 0) { 
 return EXIT_FAILURE; 
 } 
 for (i = 0; i < 20; i++) { 
 puts("a"); 
 wait_thread(); 
 } 
 if (pthread_join(thread, NULL) != 0) { 
 return EXIT_FAILURE; 
 } 
 return EXIT_SUCCESS; 
}

Пример иллюстрирует параллельное выполнение основного потока, выдающего в стандартный вывод последовательность букв "a", и дочернего потока, выдающего в стандартный поток ошибок (stderr) последовательность букв "b". Обратите внимание на особенности создания потока (pthread_create), указания его тела (исполняемой процедуры потока thread_func) и ожидания завершения дочернего потока (pthread_join).

Потоки и процессы в Solaris

В ОС Solaris, как уже было отмечено, используется модель потоков много / много. Кроме того, в системе используется также уже известное нам понятие облегченный процесс (lightweight process) промежуточное между концепцией пользовательского потока и системного потока. Таким образом, в ОС Solaris каждый пользовательский поток отображается в свой облегченный процесс, который, в свою очередь, отображается в поток ядра; последний может исполняться на любом процессоре (или ядре процессора) компьютерной системы. Схема организации потоков в Solaris изображена на рис. 10.5.

Потоки в Solaris.

увеличить изображение
Рис. 10.5. Потоки в Solaris.

На рис. 10.6 изображена схема организации процесса в ОС Solaris.

Процессы в Solaris.

увеличить изображение
Рис. 10.6. Процессы в Solaris.

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

< Лекция 9 || Лекция 10: 1234 || Лекция 11 >
Гульжан Мурсакимова
Гульжан Мурсакимова
Василий Четвертаков
Василий Четвертаков
Алихан Ергалиев
Алихан Ергалиев
Россия
Иван Иванов
Иван Иванов
Украина, Черкаси