【问题标题】:perl: Will Log::Log4perl work in a multi-threaded environment?perl: Log::Log4perl 会在多线程环境中工作吗?
【发布时间】:2012-02-13 22:59:11
【问题描述】:

我在我的 perl 脚本中使用日志记录 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...");

【问题讨论】:

  • 别管日志了,你能依靠$? 正常工作吗? :-)
  • 我应该使用什么来检查线程环境中系统代码的返回?

标签: perl logging asynchronous perl-module


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    使用 Synchronized appender 很有意义。 我的问题是: logger 变量会被传递给线程吗?根据perlthrtut 不会。我还没有验证这一点。除非有人已经这样做了?

    您可能想使用threads::shared 来共享记录器变量,但threads::shared documentation 指定您只能共享标量、数组或散列。无论如何,我已经用 perl 5.8.8 尝试过,正如预期的那样,它不会工作。

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

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

    【讨论】:

      【解决方案3】:

      Log4perl 在线程环境中工作,但是您必须仔细选择附加程序。

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

      要么为每个线程使用不同的文件,要么将 pid 添加到日志消息中。

      同步的附加程序可能会在您的线程应用程序中造成大量开销,请谨慎使用。

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

      问候,

      【讨论】:

        猜你喜欢
        • 2010-12-06
        • 2012-05-29
        • 1970-01-01
        • 2022-01-08
        • 2021-06-04
        • 2018-02-05
        • 1970-01-01
        • 2013-02-25
        • 1970-01-01
        相关资源
        最近更新 更多