Perl:如果线程启动,JSON将失败

chr*_*s01 7 perl multithreading json

如果某个线程启动,有人可以告诉我为什么JSON不工作?

use strict;
use warnings;
use JSON;
use threads;
use threads::shared;

sub th {   }

threads->create(\&th)->join() if $ARGV[0];

my $json = to_json({ val => "123"});           # WTF?!?
print "$json\n";
Run Code Online (Sandbox Code Playgroud)

工作正常并打印JSON字符串.但是1作为参数传递给脚本来创建线程并且to_json将失败

hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)
Run Code Online (Sandbox Code Playgroud)

如果我使用encode_json insead,效果相同.在JSON的联机帮助页上,单词thread不存在,我认为没有理由为什么线程会损害外部字符串转换.

???

ike*_*ami 5

JSON(.pm)只是JSON :: PP,JSON :: XS或Cpanel :: JSON :: XS的前端.

您在JSON :: XS中发现了一个错误.关于这一点,JSON :: XS的文档说:

(I-)THREADS

此模块不保证是ithread(或MULTIPLICITY-)安全,并且没有计划更改此模块.请注意,perl的内置所谓的theeads/ithreads已被正式弃用,不应使用.

[注意,最后一部分是不正确的.官方立场实际上是:线程很难,所以你应该使用别的东西.这是非常值得怀疑的,因为替代品可以说同样困难.]

解决方法:使用其他后端之一(直接或通过JSON(.pm)).

$ PERL_JSON_BACKEND=JSON::XS 46793885 0
{"val":"123"}

$ PERL_JSON_BACKEND=JSON::XS 46793885 1
hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this) at /home/ikegami/usr/perlbrew/perls/5.26.0t/lib/site_perl/5.26.0/JSON.pm line 170.

$ PERL_JSON_BACKEND=Cpanel::JSON::XS 46793885 1
{"val":"123"}

$ PERL_JSON_BACKEND=JSON::PP 46793885 1
{"val":"123"}
Run Code Online (Sandbox Code Playgroud)

您可以在加载JSON之前通过添加以下内容来控制脚本:

BEGIN { $ENV{PERL_JSON_BACKEND} = 'Cpanel::JSON::XS' }
Run Code Online (Sandbox Code Playgroud)