Функциональность потоков
Потоки, подобно процессам, характеризуются состояниями выполнения; кроме того, они могут быть синхронизированы друг с другом. Рассмотрим по очереди эти два аспекта.
Состояния потоков
Основными состояниями потоков, как и процессов, являются: состояние выполнения потока, состояние готовности и состояние блокировки. Вообще говоря, состояние приостановки нет смысла связывать с потоками, потому что такие состояния логичнее рассматривать на уровне процессов. В частности, если процесс приостанавливается, обязательно приостанавливаются все его потоки, потому что все они совместно используют адресное пространство этого процесса.
С изменением состояния потоков связаны такие четыре основных действия [ANDE97].
• Порождение. Обычно во время создания нового процесса вместе с ним создается поток этого процесса. Далее, в рамках одного и того же процесса один поток может породить другой поток, определив его указатель команд и аргументы. Новый поток создается со своим собственным контекстом регистров и стековым пространством, после чего он помещается в очередь готовых к выполнению потоков.
• Блокирование. Если потоку нужно подождать, пока не наступит некоторое событие, он блокируется (при этом сохраняется содержимое его пользовательских регистров, счетчика команд, а также указатели стеков). После этого процессор может перейти к выполнению другого готового потока.
• Разблокирование. Когда наступает событие, ожидание которого блокировало поток, последний переходит в состояние готовности.
• Завершение. После завершения потока его контекст регистров и стеки удаляются.
Важно понять, должно ли блокирование потока обязательно приводить к блокированию всего процесса. Другими словами, могут ли выполняться какие-нибудь готовые к выполнению потоки процесса, если один из его потоков блокирован? Ясно, что если блокировка одного из потоков будет приводить к блокировке всего процесса, то это существенно уменьшит гибкость и эффективность потоков.
Мы еще вернемся к обсуждению этого вопроса при сравнении потоков на пользовательском уровне и потоков на уровне ядра, а пока что рассмотрим выигрыш в производительности при использовании потоков, которые не блокируют весь процесс. На рис. 4.3 (из [KLEI96]) показана программа, выполняющая два вызова удаленных процедур (remote procedure call — RPC)2 на двух разных узлах, чтобы получить результат после их совместного выполнения. В однопоточной программе результаты получаются последовательно, поэтому программа должна ожидать, пока от каждого сервера по очереди будет получен ответ. Переписав программу так, чтобы для каждого вызова удаленной процедуры она использовала отдельный поток, можно получить существенный выигрыш в скорости. Заметим, что если такая программа работает на однопроцессорной машине, то запросы будут генерироваться последовательно; результаты тоже будут получены последовательно, однако программа будет ожидать двух ответов одновременно.
2 Вызов удаленной процедуры — это технология, при которой две программы, которые могут выполняться на разных машинах, взаимодействуют между собой с помощью синтаксиса и семантики вызовов и возвратов из процедур. Обе программы, вызывающая и вызываемая, ведут себя так, как будто они выполняются на одной и той же машине. Вызовы удаленных процедур часто применяются в приложениях, работающих по схеме клиент/сервер. Подробнее вызовы удаленных процедур обсуждаются в главе 13, "Распределенные системы".
В однопроцессорных системах многозадачность позволяет чередовать различные потоки нескольких процессов. В примере, показанном на рис. 4.4, чередуются три потока, принадлежащие двум процессам. Передача управления от одного процесса другому происходит либо тогда, когда блокируется выполняющийся поток, либо когда заканчивается интервал времени, отведенный для его выполнения.
Дата добавления: 2016-06-05; просмотров: 2315;