Спонсор: 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 >
Гульжан Мурсакимова
Гульжан Мурсакимова
Василий Четвертаков
Василий Четвертаков
Анатолий Федоров
Анатолий Федоров
Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989
Олег Волков
Олег Волков
Россия, Балаково, МБОУ СОШ 19