Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

pthread_mutex_t work_mutex; /* защищает work_area и time_to_exit */

#define WORK_SIZE 1024

char work_area[WORK_SIZE];

int time_to_exit = 0;

Далее инициализируется мьютекс:

res = pthread_mutex_init(&work_mutex, NULL);

if (res != 0) {

 perror("Mutex initialization failed");

 exit(EXIT_FAILURE);

}

Затем запускается новый

поток. Далее приведен код, выполняемый в функции потока:

pthread_mutex_lock(&work_mutex);

while(strncmp("end", work_area, 3) != 0) {

 printf("You input id characters\n", strlen(work_area)-1);

 work_area[0] = '\0';

 pthread_mutex_unlock(&work_mutex);

 sleep(1);

 pthread_mutex_lock(&work_mutex);

 while (work_area[0] == '\0') {

pthread_mutex_unlock(&work_mutex);

sleep(1);

pthread_mutex_lock(&work_mutex);

 }

}

time_to_exit = 1;

work_area[0] = '\0';

pthread_mutex_unlock(&work_mutex);

Сначала новый поток пытается заблокировать мьютекс. Если он уже заблокирован, вызов задерживается до тех пор, пока мьютекс не освободится. После получения доступа вы проверяете, нет ли к вам запроса на завершение выполнения. Если запрашивается завершение, просто задайте переменную

time_to_exit
, сотрите первый символ в рабочей области и завершите выполнение. 

Если вы не хотите завершать выполнение, сосчитайте символы и очистите первый символ, сделав его пустым (null). Пустой первый символ применяется как способ информирования считывающей программы о завершении подсчета символов. Далее вы открываете мьютекс и ждете выполнения потока

main
. Периодически вы пытаетесь заблокировать мьютекс и, когда вам это удается, проверяете, подготовил ли поток main новую работу для вас. Если нет, вы открываете мьютекс и ждете какое-то время. Если работа есть, вы считаете символы и выполняете проход цикла снова.

Далее приведен поток

main
.

pthread_mutex_lock(&work_mutex)

printf("Input some text. Enter 'end' to finish\n");

while (!time_to_exit) {

 fgets(work_area, WORK_SIZE, stdin);

 pthread_mutex_unlock(&work_mutex);

 while(1) {

pthread_mutex_lock(&work_mutex);

if (work_area[0] != '\0') {

pthread_mutex_unlock(&work_mutex);

sleep(1);

} else {

break;

}

 }

}

pthread_mutex_unlock(&work_mutex);

Он аналогичен второму

потоку. Вы блокируете рабочую область и можете читать в нее текст, а затем вы снимаете блокировку, чтобы открыть доступ другому потоку для подсчета слов. Периодически вы блокируете мьютекс, проверяете, сосчитаны ли слова (элемент
work_area[0]
равен пустому символу), и освобождаете мьютекс, если нужно продолжить ожидание. Как уже отмечалось ранее, этот вид опроса и получения ответа в основном не слишком удачный прием и в реальной жизни вам, возможно, придется применить семафор для его замены. Тем не менее, программный код справляется с задачей демонстрации примера применения мьютекса.

Атрибуты потока

Когда мы начали рассматривать потоки, то не обсуждали более сложную тему — атрибуты потока. Теперь, рассказав о синхронизации потоков — ключевой теме главы, мы можем вернуться назад и остановиться на этих характеристиках потока. Существует лишь несколько атрибутов потока, которыми вы можете управлять; здесь мы собираемся обсудить только те, которые вам понадобятся, скорее всего. Подробную информацию о других атрибутах вы можете найти в интерактивном справочном руководстве.

Во всех предыдущих примерах вы должны были повторно синхронизовать потоки с помощью функции

pthread_join
, прежде чем разрешить программе завершить выполнение. Это необходимо сделать, если вы хотите, чтобы один поток вернул данные другому потоку, создавшему данный. Иногда вам не нужно ни возвращать информацию из второго потока в поток
main
, ни заставлять поток
main
ждать этого.

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

main
продолжает обслуживать пользователя. Когда создание копии закончено, второй поток может тут же завершиться. Ему не нужно присоединяться к потоку
main
.

Вы можете создать потоки, ведущие себя подобным образом. Они называются отсоединенными или обособленными потоками, и вы создаете их, изменяя атрибуты потока или вызывая функцию

pthread_detach
. Поскольку мы хотим продемонстрировать атрибуты, то применим здесь первый метод.

Самая важная функция, которая вам понадобится, —

pthread_attr_init
, инициализирующая объект атрибутов потока:

#include <pthread.h>

int pthread_attr_init(pthread_attr_t *attr);

И снова 0 возвращается в случае успешного завершения и код ошибки в случае аварийного.

Есть и функция для уничтожения:

pthread_attr_destroy
. Ее задача — обеспечить чистое уничтожение объекта атрибутов. После того как объект уничтожен, он не может быть использован снова до тех пор, пока не будет инициализирован повторно.

Когда вы инициализировали объект атрибутов потока, можно использовать множество дополнительных функций, с помощью которых задается поведение разных атрибутов. Далее перечислены основные из них (полный список вы можете найти в интерактивном справочном руководстве, в разделе, посвященном pthread.h), но мы рассмотрим подробно только два:

detechedstate
и
schedpolicy
.

Поделиться:
Популярные книги

Ученичество. Книга 2

Понарошку Евгений
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученичество. Книга 2

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный

Неудержимый. Книга XVII

Боярский Андрей
17. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVII

Вечная Война. Книга VII

Винокуров Юрий
7. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
5.75
рейтинг книги
Вечная Война. Книга VII

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Отверженный III: Вызов

Опсокополос Алексис
3. Отверженный
Фантастика:
фэнтези
альтернативная история
7.73
рейтинг книги
Отверженный III: Вызов

Царь Федор. Трилогия

Злотников Роман Валерьевич
Царь Федор
Фантастика:
альтернативная история
8.68
рейтинг книги
Царь Федор. Трилогия

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Лорд Системы 13

Токсик Саша
13. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 13

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Темный Кластер

Кораблев Родион
Другая сторона
Фантастика:
боевая фантастика
5.00
рейтинг книги
Темный Кластер

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка