أعد تشغيل البرنامج النصي Perl متعدد الخيوط وإغلاق اتصال MySQL

StackOverflow https://stackoverflow.com/questions/1835773

سؤال

لدي برنامج نصي بيرل يقرأ ملف أمر وإعادة تشغيل نفسه إذا لزم الأمر من خلال القيام:

myscript.pl:

exec '/home/foo/bin/myscript.pl';
exit(0);

الآن، هذا يعمل بشكل جيد باستثناء قضية واحدة. لا يحتوي الخيط الذي يقرأ ملف الأمر إمكانية الوصول إلى مقبض DBI الذي أستخدمه. وعلى عدد من إعادة التشغيل، يبدو لي أن أقوم ببناء عدد اتصالات MySQL المفتوحة حتى أحصل على خطأ "العديد من الاتصالات" اللعين ". يقول مواصفات DBI:

"بسبب هذا التقييد (ربما مؤقت)، يجب أن تجعل المواضيع التي تم إنشاؤها حديثا اتصالاتها الخاصة إلى قاعدة البيانات. لا يمكن مشاركة مقابض عبر المواضيع".

بأي طريقة لإغلاق الاتصالات أو ربما طريقة مختلفة لإعادة تشغيل البرنامج النصي؟

هل كانت مفيدة؟

المحلول

استخدم متغير العلم الذي يتم مشاركته بين المواضيع. اطلب من مؤشر ترابط قراءة سطر الأوامر تعيين العلم للخروج، والبحث الذي يحمل مقبض DB إصداره ويقوم فعلا إعادة EXEC:

#!/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 عند فتحها حيث يتم فتحها، ثم استخدم Fork & Exec لإعادة تشغيل البرنامج النصي بدلا من ذلك فقط Exec. سيقوم الوالد بعد ذلك بالخروج، مما استدعاء رد الاتصال ATEXIT لإغلاق مقبض DBI. يمكن للطفل إعادة إيصال نفسه بشكل طبيعي.

تحرير: بعد التفكير في الدقائق المزدوجة، أعتقد أنك يمكن أن تخطي ATEXIT بالكامل لأن المقبض سيتم إغلاقه تلقائيا عند خروج الوالد. ما لم يكن، بالطبع، عليك القيام بعملية أكثر تعقيدا عند إغلاق مقبض DB من إغلاق ملف Filehandle بسيط.

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 لهم عندما يمكن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top