Open Source & Linux Lab

It's better when it's simple

User Tools

Site Tools


etc:teach:parallel:threads

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
etc:teach:parallel:threads [2007/10/29 09:43] – создано kkvetc:teach:parallel:threads [2008/01/03 02:32] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +FIXME в разработке
 +
 ==== Процессы, потоки ==== ==== Процессы, потоки ====
  
Line 21: Line 23:
     * имеет доступ к ресурсам процесса     * имеет доступ к ресурсам процесса
   * Аквариум с рыбами   * Аквариум с рыбами
 +
 +=== Примитивы pthreads ===
 +
 +== Создание ==
 +  * int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
 +    * thread OUT В результате успешного срабатывания функции по указанному адресу будет размещен описатель порожденного потока.
 +    * attr IN Атрибуты потока. Задают свойства потока. Может быть NULL. Описание атрибутов см. ниже.
 +    * start_routine IN Указатель на функцию потока. Выполнение потока состоит в выполнении этой функции.
 +    * arg IN/OUT Указатель, который будет передан функции потока в качестве параметра. OUT -- в том смысле, что функция потока может менять содержимое памяти с использованием этого указателя. pthread_create сожержимого не меняет, просто передает указатель функции потока. Функция потока сама интерпретирует содержание памяти по этому адресу.
 +
 +== Атрибуты ==
 +Объект задающий атрибуты потока имеет тип pthread_attr_t. Такой объект должен быть инициализирован с помощью функции
 +
 +  * int pthread_attr_init(pthread_attr_t *attr);
 +
 +В результате объект будет содержать набор свойств потока по умолчанию для данной реализации потоков. А ресурсы, которые могут использоваться в 
 +системе для хранения этих атрибутов освобождаются вызовом функции (после того, как объект был использован в вызове pthread_create и больше не нужен)
 +
 +  * int pthread_attr_destroy(pthread_attr_t *attr);
 +
 +== Присоединение и отрыв ==
 +
 +Поток может быть "присоединяемым" (joinable) или "оторванным" (detached). Для установки этого свойства в атрибутах используется функция
 +
 +  * int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
 +где detachstate можно установить в PTHREAD_CREATE_JOINABLE или в PTHREAD_CREATE_DETACHED соответственно.
 +Присоединяемые и оторванные потоки
 +
 +Для каждого присоединяемого потока, один из других потоков явно должнен вызвать функцию
 +
 +  * int pthread_join(pthread_t thread, void **value_ptr);
 +Поток, вызвавший эту функцию, останавливается, пока не окончится выполнение потока thread. Если никто не вызывает pthread_join для присоединяемого потока, то завершившись, он не освобождает свои ресурсы, а это может служить причиной утечки памяти в программе. value_ptr (OUT) -- это указатель на указатель, возвращенный функцией завершившегося потока.
 +
 +== Взаимное исключение потоков == 
 +Для организации взаимного исключения потоков при доступе к разделяемым данным используются мьютексы (mutex = mutual exclusion), объекты типа pthread_mutex_t. Мьютекс должен быть инициализирован перед использованием с помощью функкции
 +
 +  * int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
 +    * Параметр attr (IN) задает атрибуты мьютекса. Можно передать NULL для принятия атрибутов по умолчанию. Ресурсы, занимаемые мьютексом, могут быть освобождены функцией
 +
 +  * int pthread_mutex_destroy(pthread_mutex_t *mutex);
 +Для захвата мьютекса поток использует (см. пример) функцию
 +
 +  * int pthread_mutex_lock(pthread_mutex_t *mutex);
 +а для освобождения
 +
 +  * int pthread_mutex_unlock(pthread_mutex_t *mutex);
 +
 +== Условные переменные ==
 +
 +Поясним использование условных переменных на примере. Например, поток номер 1 должен выполнить некоторые действия, когда значение некоторого глобального счетчика counter достигнет критического значения criticalVal, причем значение счетчика меняет поток номер 2. Тогда, чтобы первый поток не крутился в цикле, все время проверяя значение counter, можно использовать условную переменную, с помощью которой поток номер 1 устанавливается в состояние ожидания до тех пор, пока поток номер 2 не просигналирует о наступлении нужного события:
 +
 +   * ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
 +
 +<file>
 +pthread_mutex_t mutex;
 +//условная переменная
 +pthread_cond_t cond;
 +//счетчик
 +int counter = 0;
 +</file>
 +
 +  * ПОТОК НОМЕР 1
 +
 +<file>
 +//захват мьютекса
 +pthread_mutex_lock(&mutex);
 +//если значение не равно критическому
 +if(counter!=criticalValue)
 +//останавливаемся в ожидании этого события.
 +//При этом мьютекс будет разблокирован. Как только событие наступит, 
 +//и мьютекс будет отпущен вторым потоком,
 +//мьютекс снова захватывается и выполнение потока 1 продолжается
 +    pthread_cond_wait(&cond, &mutex);
 +//обработка критического значения
 +processCriticalValue();
 +//освобождение мьютекса
 +pthread_mutex_unlock();
 +</file>
 +
 +  * ПОТОК НОМЕР 2
 +
 +<file>
 +do
 +{
 +...
 +//захват мьютекса
 +pthread_mutex_lock(&mutex);
 +//изменение значения счетчика
 +doSomethingWith(&counter);
 +//если событие наступило
 +if(counter==criticalValue)
 +//просигналировать об этом ждущим на условной переменной cond
 +    pthread_cond_signal(&cond);
 +//отпустить мьютекс
 +pthread_mutex_unlock(&mutex);
 +...
 +}while(...);
 +</file>
 +
 +Условная переменная должна быть инициализирована функцией
 +
 +  * int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
 +А ресурсы, занятые ей, могут быть освобождены функцией
 +
 +  * int pthread_cond_destroy(pthread_cond_t *cond);
 +
 +
  
      
etc/teach/parallel/threads.1193640202.txt.gz · Last modified: 2008/01/03 02:32 (external edit)