Неразделяемые переменные, такие как локальные переменные $data и $byte в предыдущем примере, не нуждаются в блокировке. Нет также необходимости блокировать ссылки на объект, если совместный доступ к этому объекту не осуществляют несколько потоков.
При использовании потоков в сочетании с объектами Perl, методы объекта часто требуют блокировать объект перед его изменением. В ином случае два потока могут попытаться изменить один объект одновременно, и это приведет к хаосу. Например, следующий метод объекта не обеспечивает безопасной поддержки потоков, поскольку два потока могут попытаться изменить объект $self одновременно.
sub acknowledge { # Не обеспечивает безопасной поддержки потоков my $ self = shif t; print $self->{socket} "200 0Kn" ; $self->{acknowledged}++; }
В таком случае можно явно блокировать объекты в методах объекта, как в предыдущем примере.
sub acknowledge { # Обеспечивает безопасную поддержку потоков my $self = shift; lock($self}; print $self->{socket} "200 OKn"; $self->{acknowledged}++; }
Поскольку переменная $self является ссылкой, может возникнуть вопрос, происходит ли при вызове функции lock () блокировка ссылки $self или объекта, на который указывает $sеlf. Ответ состоит в том, что функция lock () автоматически проходит по ссылкам вверх на один (и только один) уровень. Вызов в форме lock ($self) эквивалентен вызову lock (%$self), если $sеlf — ссылка на хеш.
В версиях Perl с поддержкой потоков предусмотрен новый синтаксис добавления атрибутов к подпрограммам. В соответствии с этим синтаксисом, за именем подпрограммы следует двоеточие и ряд атрибутов.
sub acknowledge: locked method { # Обеспечивает безопасную поддержку потоков . my $self = shift; print $self->{socket} "200 OKn"; $ self->{acknowledged}++; }
Для создания заблокированного метода применяются атрибуты locked и method, если присутствуют оба атрибута, как в предыдущем примере, то первый параметр подпрограммы (ссылка на объект) блокируется при входе в метод и освобождается после выхода.