Reputation: 553
According to the documentation it`s not thread safe for use encoding
module with threads
and it`s deprecated since perl 1.18. I use perl 5.16 on windows 7 machine. I need to covert output to windows 866 encoding. With the below code interpreter crash when try to run thread.
use utf8;
binmode(STDOUT, ':encoding(cp866)');
use threads;
my $thr = threads->create(sub {
print "поток работает";
})->detach();
sleep 1;
print "основной поток также работает";
Without binmode(STDOUT, ':cp866');
, I have "Wide characters in print" error and text shows in incorrect charset. So how should I correctly set encoding?
Upvotes: 1
Views: 180
Reputation: 385916
I replicated the problem with ActivePerl 5.16.3 x64 on Win7
I was able to resolve it by upgrading to ActivePerl 5.24.2 x64.
Cleaned up code:
use utf8;
use open ':std', ':encoding(cp866)';
use threads;
my $thr = async {
print "поток работает";
};
print "основной поток также работает";
$thr->join();
Workaround: You could encode manually instead of using PerlIO layers.
use utf8;
use threads;
use Encode qw( encode );
my $thr = async {
print encode('cp866', "поток работает");
};
print encode('cp866', "основной поток также работает");
$thr->join();
Workaround: Clone STDOUT in each thread, and apply the encoding layer to the non-shared clone.
use utf8;
use threads;
my $thr = async {
open(my $fh, '>&=:encoding(cp866)', \*STDOUT) or die $!;
*STDOUT = $fh;
print "поток работает";
};
open(my $fh, '>&=:encoding(cp866)', \*STDOUT) or die $!;
*STDOUT = $fh;
print "основной поток также работает";
$thr->join();
(This doesn't clone the underlying file descriptor, so the change is very transparent.)
Upvotes: 2