perl:Log :: Log4perl会在多线程环境中工作吗?

时间:2012-02-13 22:59:11

标签: perl logging asynchronous perl-module

我在perl脚本中使用log vai Log :: Log4perl;我想知道是否多次调用写入同一个日志对象会导致错误/错误的行为。

我正在使用Appender :: File以下列方式写出日志:

$log->info("Launching commands...");
foreach my $param (@params) {
    push @thread_handles, async {
        system("$param");
        $log->info("$param COMPLETE");
        logstatus($?);
    };
}

$_->join() foreach @thread_handles;
$log->info("Commands completed...");

3 个答案:

答案 0 :(得分:2)

具有default file based appender的Log :: Log4perl将起作用,但在使用相同日志文件的多线程或多处理环境中可能会出现一些重叠。

一种解决方案是使用Log::Log4perl::Appender::Synchronized作为追加者。有关详细信息,请参阅常见问题解答中的How can I run Log::Log4perl under mod_perl?

答案 1 :(得分:1)

使用Synchronized appender非常有意义。 我的问题是: 记录器变量是否会传递给线程?根据{{​​3}}它不会。我还没有验证这一点。除非有人已经完成了吗?

您可能很想使用threads::shared来共享记录器变量,但perlthrtut指定您只能共享标量,数组或哈希值。无论如何我用perl 5.8.8尝试过,正如预期的那样,它不会起作用。

另一种方法是为将在线程中调用的每个子例程创建一个单独的记录器。可以配置log4perl appender以避免锁定和交错。但我非常关注为每个活动线程生成单独的记录器实例所带来的性能影响。

更新: 事实证明,一个人不必变得复杂。如果你初始化log4perl就好像你正在编写单个线程脚本并且你没有任何特殊技巧就调用了logger对象方法,那么一切都像宣传的那样工作。记录器对象不必传递给线程入口点。在线程入口点中调用的sub可以像调用常规方式一样访问logger方法。 Synchronized appender使所有内容保持一致。

答案 2 :(得分:0)

Log4perl正在使用线程环境,但是你必须仔细选择appender。

除了已同步的appender之外,带缓冲的日志消息似乎没有按顺序排列,但这不是问题。

为每个线程使用不同的文件或将pid添加到logmessage。

同步的appender可能会在您的线程应用程序中造成大量开销,请小心使用它。

我选择带有pid或某种线程标识符的单个日志文件。我正在使用这种日志记录。

的问候,