perl:多线程写入和尾文件

发布于 2024-12-16 16:13:16 字数 597 浏览 0 评论 0原文

我正在研究 perl 多线程的一个简单用例:一个线程写入文件,另一个线程跟踪文件。这是代码:

use strict;
use warnings;
use threads;
use File::Tail;

my $file = 'data.txt';
sub tail_file{
    my $file=File::Tail->new($file);
    while (defined(my $line=$file->read)) {
        print "$line";
    }
}

sub write_file{
    open (MYFILE, ">> $file");
    print MYFILE scalar localtime .  "  A data.\n";
    close (MYFILE); 
    print 'write done!';
}

my $t_tail = threads->new(\&tail_file);
$t_tail->join();

my $t_write = threads->new(\&write_file);
$t_write->join();



运行时,该程序卡在控制台上。

I'm working on a simple use-case of perl multi-thread: one thread writes to a file and another thread tails the file. here is the code:

use strict;
use warnings;
use threads;
use File::Tail;

my $file = 'data.txt';
sub tail_file{
    my $file=File::Tail->new($file);
    while (defined(my $line=$file->read)) {
        print "$line";
    }
}

sub write_file{
    open (MYFILE, ">> $file");
    print MYFILE scalar localtime .  "  A data.\n";
    close (MYFILE); 
    print 'write done!';
}

my $t_tail = threads->new(\&tail_file);
$t_tail->join();

my $t_write = threads->new(\&write_file);
$t_write->join();



When running, this program is stuck on the console.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里兽 2024-12-23 16:13:16

如果您摆脱对 $t_tail->join() 的调用,您的程序实际上可以正常工作。您需要摆脱此调用,因为您的 $t_tail 线程将永远运行(因此永远不会 join),并且您的 $t_write 线程永远不会被踢掉。

但是,您应该知道,即使您删除了该行,如果 $t_write 线程在 $t_tail 线程之前执行(因为线程的执行顺序是永远不会保证),那么可能会出现这样的情况:在 File::Tail 对象初始化之前就完成了对文件的写入。由于 File::Tail 仅捕获初始化后发生的文件更改,因此可能看起来什么也没有发生。

最后,您可能认为 File::Tail 的工作方式与 Linux/Unix tail 类似,但是 文档 显示该模块使用的默认等待时间与 Linux/Unix 对应版本相比相当慷慨:

最大间隔

将花费的最大秒数(实数)
睡眠。默认值为 60,这意味着 File::Tail 的花费永远不会超过
六十秒不检查文件。

间隔

将花费的初始秒数(实数)
在第一次检查文件之前睡觉。默认为十秒,
意思是 File::Tail 将休眠 10 秒,然后确定,如何
文件中出现了许多新行。

如果您运行程序,并且您的 File::Tail 对象在开始写入文件之前确实已初始化,那么您可能需要等待一段时间(10 秒)才能看到任何内容你的控制台。

If you get rid of the call to $t_tail->join(), your program actually works fine. You need to get rid of this call because your $t_tail thread will run forever (and thus will never join), and your $t_write thread will never get kicked off.

You should know, however, that even if you get rid of that line, if the $t_write thread executes before the $t_tail thread (since the order of execution with threads is never guaranteed), then it may be the case you finish writing to the file before your File::Tail object is even initialized. And since File::Tail only captures changes to the file that happen after it is initialized, it may look like nothing is happening at all.

Lastly, you may think that File::Tail works similarly to the Linux/Unix tail, but the documentation shows that the default wait times used by the module are quite generous in comparison to the Linux/Unix counterpart:

maxinterval

The maximum number of seconds (real number) that will be spent
sleeping. Default is 60, meaning File::Tail will never spend more than
sixty seconds without checking the file.

interval

The initial number of seconds (real number) that will be spent
sleeping, before the file is first checked. Default is ten seconds,
meaning File::Tail will sleep for 10 seconds and then determine, how
many new lines have appeared in the file.

If you run your program, and your File::Tail object does happen to get initialized before you start writing to the file, then you may have to wait a while (10 seconds) before you see anything on your console.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文