重启多线程的perl脚本和关闭MySQL连接
-
11-09-2019 - |
题
我有一个Perl脚本,读取命令文件并且通过这样做,如果必要重新启动本身:
myscript.pl:
exec '/home/foo/bin/myscript.pl';
exit(0);
现在,这个工程除了一个问题很好。读取命令文件中的线程没有访问我使用DBI句柄。并在重新启动次数我似乎建立开放式的MySQL连接数,直到我得到了可怕的“太多的连接”的错误。在DBI规范说:
“正因为如此(可能是暂时的)的限制,新创建线程必须使自己连接到数据库中。把手不能在线程间共享。”
任何方式关闭连接或可能以不同的方式来重新启动脚本?
解决方案
使用被线程之间共享的标记变量。有命令行读线程设置标志退出,该线程持有DB手柄释放它,实际上做的重新执行中:
#!/usr/bin/perl
use threads;
use threads::shared;
use strict; use warnings;
my $EXIT_FLAG :shared;
my $db_thread = threads->create('do_the_db_thing');
$db_thread->detach;
while ( 1 ) {
sleep rand 10;
$EXIT_FLAG = 1 if 0.05 > rand or time - $^T > 20;
}
sub do_the_db_thing {
until ( $EXIT_FLAG ) {
warn sprintf "%d: Working with the db\n", time - $^T;
sleep rand 5;
}
# $dbh->disconnect; # here
warn "Exit flag is set ... restarting\n";
exec 'j.pl';
}
其他提示
您可以尝试注册一个atexit对功能在其被打开点,关闭DBI句柄,然后用叉子和exec来重新启动脚本,而并非只是高管。然后,父母会调用exit,调用atexit对回调关闭DBI句柄。子可以正常重新exec的本身。
编辑:想了一对夫妇分钟后,我相信你可以跳过完全是因为把手会在父母的退出自动关闭的atexit。除非,当然,你需要在关闭DB手柄不仅仅是一个简单的文件句柄接近做更复杂的操作。
my $pid = fork();
if (not defined $pid) {
#Could not fork, so handle the error somehow
} elsif ($pid == 0) {
#Child re-execs itself
exec '/home/foo/bin/myscript.pl';
} else {
#Parent exits
exit(0);
}
如果您希望很多连接,你可能想 DBI :: GOFER 行动为你DBI代理。你在尽可能多的脚本创造尽可能多的连接,只要你喜欢,和DBI :: GOFER分享他们的时候就可以了。
不隶属于 StackOverflow