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

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

Жанры

Основы программирования в 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
.

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

Большая книга о новой жизни, которую никогда не поздно начать (сборник)

Норбеков Мирзакарим Санакулович
Дом и Семья:
здоровье и красота
5.00
рейтинг книги
Большая книга о новой жизни, которую никогда не поздно начать (сборник)

Моров. Том 1 и Том 2

Кощеев Владимир
1. Моров
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Моров. Том 1 и Том 2

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Чужак из ниоткуда 2

Евтушенко Алексей Анатольевич
2. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 2

Гром Раскатного. Том 2

Володин Григорий Григорьевич
2. Штормовой Предел
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Гром Раскатного. Том 2

На границе империй. Том 10. Часть 5

INDIGO
23. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 5

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Украсть у президента

Гриньков Владимир Васильевич
Детективы:
триллеры
5.00
рейтинг книги
Украсть у президента

Простолюдин

Рокотов Алексей
1. Путь князя
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Простолюдин

Я до сих пор князь. Книга XXII

Дрейк Сириус
22. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор князь. Книга XXII

Перешагнуть пропасть

Муравьёв Константин Николаевич
1. Перешагнуть пропасть
Фантастика:
боевая фантастика
космическая фантастика
8.38
рейтинг книги
Перешагнуть пропасть

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Артефактор. Возвращение блудного императора

Седых Александр Иванович
2. Артефактор
Фантастика:
фэнтези
боевая фантастика
4.33
рейтинг книги
Артефактор. Возвращение блудного императора