my %h : shared; my %mutexes : shared; sub get_mutex { my ($k) = @_; my $mutex_ref = $mutexes{$k}; return $mutex_ref if $mutex_ref; lock($mutexes); my $new_mutex : shared; return $mutexes{$k} ||= \$new_mutex; } sub safe_set { my ($k, $v) = @_; lock ${ get_mutex($k) }; $h{$k} = $v; }