Шрифт:
•
•
•
•
•
После запуска потока все атрибуты, связанные с завершаемостью потока, могут быть изменены вызовами
Передача параметров потоку
Зачастую каждый поток из группы последовательно создаваемых потоков, выполняющих одну и ту же функцию, нужно запускать со своим индивидуальным блоком данных (параметром потока). Для этого предназначен 4-й параметр вызова
Достаточно часто встречающийся на практике образец многопоточного кода — это циклическая процедура ожидания наступления некоторого условия (события), после которого порождается новый экземпляр потока, призванный обслужить наступившее событие (типичная схема всего разнообразия многопоточных сетевых серверов). В таких случаях код, порождающий потоки, выглядит подобно следующему фрагменту:
Этот простейший код крайне опасен: при быстрых циклах и, что намного важнее, непредсказуемых моментах повторных созданий экземпляров потоков из вызывающего цикла необходимо обеспечить, чтобы используемое в функции потока
Здесь блок данных, выделяемый в стеке порождающего потока, к началу его использования в дочернем потоке может быть просто уничтожен.
Единственно надежный способ обеспечить требование актуальности передаваемых данных - это создание копии блока параметров непосредственно при входе в функцию потока, например так (если определена операция копирования):
или так (если определен инициализирующий конструктор структуры данных):
Но и этот код оказывается некорректен. При порождении потока нам нужно, чтобы инициализация копии переданных данных в теле функции потока произошла до того, как на очередном цикле оригинал этих данных будет разрушен или изменен. Но дисциплины диспетчеризации равнозначных потоков (в данном случае родительского и порожденного) в операционной системе никак не регламентируют (и не имеют права этого делать!) порядок их выполнения после точки ветвления —
Обеспечить актуальность копии переданных данных можно несколькими искусственными способами:
1. Передачей в качестве аргумента