(重复我在 PerlMonks 上说过的话……)
BEGIN {
my $mutex;
sub that {
$mutex ||= APR::ThreadMutex->new( $r->pool() );
$mutex->lock();
$ENV{TZ}= ...;
...
$mutex->unlock();
}
}
但是,当然,lock() 应该发生在 c'tor 中,而 unlock() 应该发生在 d'tor 中,除了一次性的 hack。
更新:请注意,在子例程中如何初始化 $mutex 存在竞争条件(两个线程可以几乎同时第一次调用 that())。您很可能希望在创建(附加)线程之前初始化 $mutex,但我不清楚“worker”Apache MPM 的详细信息以及如何轻松完成此操作。如果有一些代码“提前”运行,只需从那里调用 that() 即可消除竞争。
这一切都表明 APR::ThreadMutex 的接口更安全:
BEGIN {
my $mutex;
sub that {
my $autoLock= APR::ThreadMutex->autoLock( \$mutex );
...
# Mutex automatically released when $autoLock destroyed
}
}
请注意,autoLock() 获取对 undef 的引用会导致它在初始化 $mutex 时使用互斥锁来防止竞争。