Greetings,
I tested BrowserUk's example using a semaphore lock and sometimes fail on macOS; even with auto flush enabled. I thought that this would work but is not consistent on macOS that is. Two of the lines were combined into one super long line.
Be sure to direct the output to STDERR when testing; i.e. 2>output.txt on UNIX. The output file is 3.4 GiB.
use strict;
use warnings;
use threads;
use threads::shared;
# enable autoflush on the handle
STDERR->autoflush;
my $sem_stderr :shared;
sub print_err { lock $sem_stderr; print STDERR @_; }
sub task {
my $id = shift;
my $str = "ab " x 3000;
for (1..10000) {
print_err($str, "\n");
}
}
threads->create('task', $_) for 1..40;
$_->join for threads->list;
MCE::Shared was released some time after BrowserUk's response. Using MCE::Shared, auto flush is enabled behind the scene during construction. This example runs consistently without garbled output.
use strict;
use warnings;
use threads;
use MCE::Shared;
mce_open my $err_fh, '>>', \*STDERR;
sub task {
my $id = shift;
my $str = "ab " x 3000;
for (1..10000) {
print $err_fh $str, "\n";
}
}
threads->create('task', $_) for 1..40;
$_->join for threads->list;
Does your Perl binary lack threads support? If yes, MCE::Shared also works with child processes. Here is the same thing using MCE::Hobo.
use strict;
use warnings;
use MCE::Hobo;
use MCE::Shared;
mce_open my $err_fh, '>>', \*STDERR;
sub task {
my $id = shift;
my $str = "ab " x 3000;
for (1..10000) {
print $err_fh $str, "\n";
}
}
MCE::Hobo->create('task', $_) for 1..40;
$_->join for MCE::Hobo->list;
md5sum and word count:
MD5 (output.txt) = b5bf2b49acd0926a9fa156def91579a0
400000 1200000000 3600400000 output.txt
Regards, Mario |