2017-11-27 14 views
1

ドキュメンテーションによると、スレッドセーフではありませんencodingモジュールthreadsとperl 1.18から非推奨です。私はWindows 7マシンでperl 5.16を使用します。私はWindows 866エンコーディングに出力を変換する必要があります。スレッドを実行しようとすると、以下のコードインタプリタがクラッシュします。 binmode(STDOUT, ':cp866');なしスレッドセーフなSTDOUTエンコーディングをPerlでどのように設定できますか?

use utf8; 
binmode(STDOUT, ':encoding(cp866)'); 
use threads; 


my $thr = threads->create(sub { 
    print "поток работает"; 
})->detach(); 

sleep 1; 
print "основной поток также работает"; 

、私は「印刷中にワイド文字」エラーとテキストが正しくない文字コードで示しています。だから私は正しくエンコーディングを設定する必要がありますか?

答えて

2

私はActivePerlの5.24.2のx64にアップグレードすることで、それを解決することができましたwin7の

上のActivePerl 5.16.3の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(); 

(これは基本的なファイルディスクリプタのクローンを作成しませんので、変更は非常に透明である。)

関連する問題