根据文档,使用 encoding
模块与 threads
不是线程安全的,并且自 perl 1.18 起已弃用。我在 Windows 7 机器上使用 perl 5.16。我需要将输出转换为 windows 866 编码。尝试运行线程时,以下代码解释器崩溃。
use utf8;
binmode(STDOUT, ':encoding(cp866)');
use threads;
my $thr = threads->create(sub {
print "поток работает";
})->detach();
sleep 1;
print "основной поток также работает";
如果没有 binmode(STDOUT, ':cp866');
,我会出现“打印中的宽字符”错误,并且文本以不正确的字符集显示。那么应该如何正确设置编码呢?
最佳答案
我在 Win7 上用 ActivePerl 5.16.3 x64 复制了这个问题
我能够通过升级到 ActivePerl 5.24.2 x64 来解决它。
清理代码:
use utf8;
use open ':std', ':encoding(cp866)';
use threads;
my $thr = async {
print "поток работает";
};
print "основной поток также работает";
$thr->join();
解决方法:您可以手动编码而不是使用 PerlIO 层。
use utf8;
use threads;
use Encode qw( encode );
my $thr = async {
print encode('cp866', "поток работает");
};
print encode('cp866', "основной поток также работает");
$thr->join();
解决方法:在每个线程中克隆 STDOUT,并将编码层应用于非共享克隆。
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();
(这不会克隆底层文件描述符,因此更改非常透明。)
关于windows - 如何在 Perl 中线程安全地设置 STDOUT 编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47519665/