Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
exit(EXIT_FAILURE); }Обратите внимание на то, что начальное значение семафора равно 0.
В функции
mainsem_post printf("Input some text. Enter 'end' to finishn"); while(strncmp("end", work_area, 3) != 0) { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); }В новом потоке вы ждете семафор и затем подсчитываете символы ввода:
sem_wait(&bin_sem); while(strncmp("end", work_area, 3) != 0) { printf("You input %d charactersn", strlen(work_area)-1); sem_wait(&bin_sem); }Пока семафор установлен, вы ждете ввода с клавиатуры. Когда вы получите некоторый ввод, то освобождаете семафор, разрешив второму потоку сосчитать символы перед тем, как первый поток начнет снова считывать ввод с клавиатуры.
И опять потоки совместно используют один и тот же массив
work_areasem_waitДайте программе отработать:
$ <b>cc -D_REENTRANT thread3.с -о threads -lpthread</b>$ <b>./thread3</b>Input some text. Enter 'end', to finish<b>The Wasp Factory</b>You input 16 characters<b>Iain Banks</b>You input 10 characters<b>end</b>Waiting for thread to finish...Thread joinedВ программах с потоками временные ошибки всегда трудно найти, но программа кажется приспособленной и к быстрому вводу текста, и более неспешным паузам.
Как это работает
Когда вы инициализируете семафор, то задаете ему начальное значение, равное 0. Следовательно, когда запускается функция потока, вызов
sem_waitВ потоке
mainsem_postsem_waitsem_waitsem_postНеочевидные недочеты в разработке, которые заканчиваются в результате неявными ошибками, легко пропустить. Давайте слегка изменим программу на thread3a.c, так чтобы вводимый с клавиатуры текст временами заменялся автоматически формируемым текстом. Замените цикл чтения в
mainprintf("Input some text. Enter 'end' to finishn");while (strncmp("end", work_area, 3) != 0) { if (strncmp(work_area, "FAST", 4) == 0) { sem_post(&bin_sem); strcpy(work_area, "Wheeee..."); } else { fgets(work_area, WORK_SIZE, stdin); } sem_post(&bin_sem);}Теперь, если вы введете
FASTsem_postwork_area$ <b>cc -D_REENTRANT thread3a.с -о thread3a -lpthread</b>$ <b>./thread3a</b>Input some text. Enter 'end' to finish<b>Excession</b>You input 9 characters<b>FAST</b>You input 7 charactersYou input 7 charactersYou input 7 characters<b>end</b>Waiting for thread to finish...Thread joinedПроблема этой программы заключается в том, что она рассчитывала на то, что ввод текста из программы продлится так долго, что у другого потока хватит времени для подсчета символов до того, как поток
mainFASTWheeee...Этот пример показывает, как аккуратны вы должны быть с временны́ми условиями в многопоточных программах. Исправить программу можно, применяя дополнительный семафор для того, чтобы заставить поток
mainСинхронизация с помощью мьютексов
Другой способ синхронизации доступа в многопоточных программах — применение мьютексов (сокращение от mutual exclusions — взаимные исключения) или исключающих семафоров, которые разрешают программистам "запирать" объект так, что только один поток может обратиться к нему.
Базовые функции, необходимые для использования мьютексов, очень похожи на функции семафоров. Они объявляются следующим образом:
