Bal*_*nan 1 scripting perl multithreading memory-management threadpool
当我调用我的多线程perl脚本时,在几个场景中,它会引发一些类似于以下的异常.对不起,我无法分享代码.但如果真的需要我可以尝试构建一个片段(如果确实需要).因为我猜这应该有一些理论上的答案.
*** glibc detected *** perl: double free or corruption (!prev): 0x00007f775401e9a0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3d74c75e66]
/lib64/libc.so.6[0x3d74c789b3]
/lib64/libc.so.6[0x3d74c7b880]
/lib64/libc.so.6(realloc+0xe5)[0x3d74c7baf5]
/usr/lib/../lib64/libcrypto.so.10(CRYPTO_realloc+0x5f)[0x7f775907bd8f]
/usr/lib/../lib64/libcrypto.so.10(lh_insert+0xee)[0x7f77590f763e]
/usr/lib/../lib64/libcrypto.so.10(OBJ_NAME_add+0x6b)[0x7f775907f12b]
/usr/lib/../lib64/libcrypto.so.10(EVP_add_cipher+0x27)[0x7f7759102387]
/usr/lib/../lib64/libcrypto.so.10(OpenSSL_add_all_ciphers+0x4b7)[0x7f7759106a07]
/usr/lib/../lib64/libcrypto.so.10(OPENSSL_add_all_algorithms_noconf+0xe)[0x7f775910653e]
/usr/local/lib/libssh2.so.1(libssh2_init+0x39)[0x7f77596800b9]
Run Code Online (Sandbox Code Playgroud)
为什么我会收到这样的错误?
我正在使用Thread :: Queue; 使用threads :: shared; 请让我知道你的看法.
下面是线程库版本信息.
use threads; - installed v2.15 (latest - 2.16)
use Thread::Queue; - installed v3.12 (up to date)
use threads::shared; - installed v1.56 (latest - 1.57)
perl - installed v5.26.1
Run Code Online (Sandbox Code Playgroud)
其他图书馆::
use YAML::XS 'LoadFile'; - 0.66 up to date
use Net::Netconf::Manager; - 1.02 up to date
use Config::Properties; - 1.80 up to date
use Sys::Syslog; - 0.35 up to date
use DateTime::Format::Strptime; - 1.74 up to date
use DateTime; - 1.44 up to date
use XML::LibXML; - 2.0129 (latest 2.0139)
use Regexp::Common qw/net/; - 2017060201 up to date
use Getopt::Long; - 2.5 up to date
Run Code Online (Sandbox Code Playgroud)
为了给你一个坚定的答案,我们需要一些我们可以运行和排除故障的东西.否则错误不可重现.
话虽如此 - 这看起来类似于我以前遇到的某些模块不是线程安全的东西 - 它们通常运行正常,然后偶尔会在你的脸上爆炸.
例如Crypt :: SSLeay早在2008年.Net :: SSLeay在1.4.2之前
一般的解决方法是在编译时停止加载罪犯use- 因为所有线程都会继承相同的状态 - 而是在线程中,在运行时用require和加载它们import.通过这样做,你将它们隔离开来 - 你的线程开始需要稍微长一点,但你不应该在perl中发送垃圾邮件.
或者使用线程安全的其他模块.
随着您的更新和屏幕截图 - Net::SSH2提到 - 这意味着您的其他模块之一正在拉动它.
但是Net :: SSH线程安全表明libssh可能对线程安全有一些限制:
线程安全:只是不要同时共享句柄
你没有明确提到使用它,但看起来它被另一个模块拉入.猜测一下,那就是Net::Netconf::Manager.
而作为第二个进一步的猜测 - 它可能正在做'共享句柄',因为它没有意识到它是在一个线程中运行.
所以这个模块是我建议在线程中隔离的模块:
require 'Net::NetConf::Manager';
Net::NetConf::Manager -> import;
Run Code Online (Sandbox Code Playgroud)
并在线程内进行实例化.
当您使用工作线程模型时,这应该是最小的开销,并且意味着您没有遇到此问题.
但更一般地说 - 假设模块是线程安全的,除非他们明确说明它们是不明智的,这是不明智的.主要的"跳闸"点通常是模块可以假定/暗示任何类型的资源共享,例如网络套接字,文件句柄,数据库连接等.通常在实例化时创建套接字(例如,您传递用户名的位置) /密码)并且有两个线程试图同时驱动套接字是一种潜在的竞争条件.