русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Нити и семафоры нитей в Linux

Нити

В операционных системах нити являются параллельными потоками выполнения в составе одного процесса. (Некоторые переводчики переводят термин "thread" - "нить" - как "поток".) В составе процесса может быть запущено несколько нитей, которые выполняются параллельно (или квазипараллельно - в режиме разделения времени процессора). Можно считать (и в некоторых операционных системах это действительно так), что в любом процессе имеется по крайней мере одна нить - главная - та, в которой выполняется функция main . Главная нить может порождать другие нити. В программе процесса нить имеет вид процедуры/функции, которая вызывается специальным системным вызовом и после вызова выполняется параллельно с запустившей ее нитью.

Нити, принадлежащие одному процессу, совместно используют почти все ресурсы своего процесса. Однако у каждой нити имеются и некоторые собственные ресурсы. Очевидно, что первым таким собственным ресурсом нити является процессорное время. Два других собственных ресурса нити - вектор состояния и стек. Наличие у нити собственного вектора состояния позволяет системе прерывать и возобновлять выполнение нитей, то есть, планировать нити в режиме вытесняющей многозадачности. Наличие у нити собственного стека позволяет запускать на параллельное выполнение несколько экземпляров одной и той же процедуры/функции. Поскольку локальные переменные функции размещаются в стеке, каждая нить имеет свой набор локальных переменных, которые независимы от других нитей. Статические же переменные программы - общие для всех нитей, также все нити используют один и тот же экземпляр кода функции.

При введении понятия нитей разработчики систем имели в виду два их возможных предназначения:

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

В клонах операционной системы Unix имеется два подхода к обеспечению механизма нитей:

  • В некоторых операционных системах этого семейства (например, Open Unix) в ядро системы включены "виртуальные процессоры", так называемые, легковесные процессы, специально поддерживающие многопоточность. Соответственно, системные вызовы, обеспечивающие работу с нитями, обращаются непосредственно к ядру и используют механизм легковесных процессов.
  • Разработчики других операционных систем (например, Free BSD) исходили из того, что в клонах Unix создание "полноценного" процесса - операция сама по себе быстрая, таким образом, они видели свою основную задачу в обеспечении возможности совместного использования ресурсов нитями. Эту задачу они решили введением в ядро такого расширения системного вызова fork, которое обеспечивает наследование дочерним процессом любых (по выбору программиста) ресурсов родительского процесса. Для совместимости с ранее разработанным программным обеспечением сам системный вызов fork остается без изменений, а его расширение получает другое имя (в Free BSD - pfork). Нить в таких системах фактически представляет собой отдельный процесс, использующий ресурсы родительского процесса совместно с ним.

Поскольку статическая память программы - общая для всех нитей, при работе с совмесно используемыми переменными возможны конфликты доступа. Конфликты могут возникать при одновременном обращении к таким переменным. Проявляются такие конфликты не в отказе в доступе или в фатальных ошибках, а в возможном нарушении целостности совместно используемых данных. Ответственность за сохранение такой целостности лежит на программисте. Программист должен обеспечить, чтобы логически законченные операции над совместно используемыми данными выполнялись как транзакции, то есть, во время их выполнения другие нити, выполняющиеся параллельно, не могли изменять значения этих же данных. Участки кода программы, выполняющие такую работу с совместно используемыми ресурсами, называются критическими секциями. Для обеспечения целостности требуется, чтобы две или более нитей не могли находиться своих критических секциях одновременно. Это - проблема, наиболее часто возникающая при программировании многопоточных приложений, однако, задачи синхронизации и подсчета ресурсов в таких приложениях также возникают. Для решения этой проблемы можно применять обычные семафоры - как и в аналогичных задачах для процессов. Однако целей работы с нитями во многих операционных системах вводятся специальные средства, предназначенные для обеспечения взаимодействий только в пределах одного процесса. Это "облегченные" семафоры-счетчики ресурсов, исключа.щие семафоры и сигнализирующие семафоры. Фактически все эти средства представляют собой обычные семафоры, используемые только в пределах одного процесса, однако, интерфейсы этих средств отличается от интерфейса семафоров процессов и является более специфичными и удобным в применении.

 

 

Системные вызовы Unix/Linux

Стандартами POSIX и Single Unix Specification установлен API для нитей. В операционной системе Linux механизм реализации нитей следует подходу BSD: в системе имеется вызов clone, непосредственно обращающийся к ядру системы и представляющий собой расширенную версию fork, стандартный же API обеспечивается функциями библиотеки pthread, которые являются надстройками над вызовом clone .

Следующие функции библитеки нитей, соответствующие стандарту, обеспечивают основные связанные с работой нитей операции в Linux. (Перечислены не все возможности библиотеки pthread).

 

 

Выполнение нитей

Функция pthread_create создает новую нить. Этой функции передается указатель на атрибуты выполнения нити (большинство нитей выполняется со стандартными атрибутами), указатель на потоковую функцию (функцию, выполняемую в нити), параметр потоковой функции, адрес переменной типа pthread_t, в которую pthread_create записывает идентификатор созданной нити. Функция pthread_create запускает потоковую функцию в новой нити, и она выполняется параллельно с другими нитями процесса.

Потоковая функция имеет прототип:

    void * имя_функции(void *);

И параметр, и возвращаемое значение такой функции - указатели, таким образом, функция может принимать и возвращать любую информацию.

Нить завершается при завершении выполнения потоковой функции или при выполнении функции pthread_exit .

Функция pthread_join применяется для нитей так же, как системный вызов wait применяется для процессов: она заставляет вызвавшую ее нить ожидать завершения указанной в вызове нить и позволяет вызвавшей нити получить значение, которое вернула завершившаяся нить.

Выполнение нити может быть принудительно прекращено из другой нити при помощи функции pthread_cancel, которой задается идентификатор "убиваемой" нити.

 

 

Исключающие семафоры

Исключающий семафор представляется в Linux-программе переменной типа pthread_mutex_t. Семафор должен быть инициализирован при помощи функции pthread_mutex_init . Как правило, приложения удовлетворяют стандартные параметры инициализации исключающих семафором.

Функции pthread_mutex_lock и pthread_mutex_unlock аналогичны семафорным операциям P и V соответственно. Функция pthread_mutex_trylock аналогична pthread_mutex_lock , но при невозможности захватить семафор не переводит нить в ожидание, а возвращает соответствующий признак.

Фактически исключающий семафор является обычным двоичным семафором с начальным значением 1.

 

 

Сигнализирующие семафоры

Сигнализирующий семафор представляется в Linux-программе переменной типа pthread_cond_t. Фактически такой семафор является обычным двоичным семафором с начальным значением 0. Семафор должен быть инициализирован при помощи функции pthread_cond_init . Параметров инициализации нет.

Функция pthread_cond_wait реализует на сигнальном семафоре семафорную операцию P . Она блокирует вызвавшую ее нить до тех пор, пока не будет получен сигнал об установке семафора в 1.

Функция pthread_cond_signal аналогична семафорной операции V она разблокирует одну из нитей, ожидающих на семафоре. Функция pthread_cond_broadcast разблокирует все нити, ожидающие на семафоре.

 

 

Счетчики ресурсов

Счетчики ресурсов для нитей - это обыкновенные общие семафоры. Такой семафор представляется в программе переменной типа sem_t. Такой семафор должен быть инициализирован при помощи функции sem_init, а затем к нему могут применяться функции sem_wait и sem_post, выполняющие соответственно P- и V -операции.

Функция sem_getvalue позволяет узнать текущее значение семафора.

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

cc -o ganesha8 ganesha8.o -lpthread

Внимание! Хотя мы и рекомендуем нашим студентам книгу М.Митчел, Дж.Оулдем, А.Самьюэл "Программирование для Linux", советуем относиться к примерам этой книги осторожно: так, программный код, приведенный в ней на стр. 90-91 (Глава - "Потоки") , ведет к тупику.

Пример выполнения приведен здесь.


Справочный материал

Избранные системные вызовы Linux/Unix. Краткое описание.

Cправочник библиотечных функция языка С: часть 1, часть 2 (кодировка кириллица ibm866).


Просмотров: 10617

Вернуться в оглавление:ОС Linux




Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Полезен материал? Поделись:

Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.