2015-01-03 2 views
3

Я пытаюсь использовать потоки в моем приложении perl/tk, чтобы он не замерзал при подключении к удаленному серверу mysql.используя потоки perl/tk, чтобы избежать зависания окна/не отвечает

#!/usr/bin/perl 
use warnings; 
use strict; 
use DBI; 
use DBD::mysql; 
use Tk; 
use threads; 
use threads::shared; 

our $type="mysql"; 
our $database="b_db"; 
our $host="mysite.com"; 
our $port="3306"; 
our $tablename="tc"; 
our $user="example"; 
our $pwd="********"; 
our $dsn="dbi:$type:$database:$host:$port"; 

my $thr=threads->create(\&con); 

our $mw=new MainWindow; 
$mw->Button(-text=>"Connect",-command=>\&con)->pack; 
MainLoop; 
sub con{ 
    our $connect=DBI->connect($dsn,$user,$pwd)or die &mysql_Err; 
    print "done connecting\n" if $connect; 
    print "error\n" unless $connect; 
} 
$thr->detach; 

но он все еще зависает, когда он пытается соединиться. Я пытался использовать тк/fileevent:

#!/usr/bin/perl 
use DBI; 
use DBD::mysql; 
use Tk; 

our $type="mysql"; 
our $database="b_db"; 
our $host="mysite.com"; 
our $port="3306"; 
our $tablename="tc"; 
our $user="example"; 
our $pwd="********"; 
our $dsn="dbi:$type:$database:$host:$port"; 

our $mw=new MainWindow; 
$mw->Button(-text=>"Connect",-command=>\&con)->pack; 

sub con{ 
    our $connect=DBI->connect($dsn,$user,$pwd)or die &mysql_Err; 
    $mw->fileevent($connect, "readable", \&contquery); 
} 

sub contquery{ 
    $query="SELECT * FROM products ORDER BY id"; 
    $queryhandle=$connect->prepare($query); 
    $queryhandle->execute; 
    $queryhandle->bind_columns(undef, \$product_id, \$price, \$product_name, \product_type); 
    while($queryhandle->fetch()){ 
     print <<print; 
Product Name: $product_name | Type: $product_type | Prict: $price 
print 
    } 
} 
MainLoop; 

, но она по-прежнему замерзает. Может ли кто-нибудь посоветовать мне, что может быть причиной этого?

ответ

2

Вы недопонимаете резьбу и разделение. our не имеет отношения к нити. Для этого вам нужно объявить переменную как shared.

В противном случае с момента вашего create subthread у них есть своя локальная копия всех переменных. Это почти наверняка будет вашей проблемой - ваш поток подключается к базе данных, а затем выходит, полностью независимый от основного потока.

our также не делает то, что вы думаете, что он делает - это для обмена переменными пакета (например, ничего не связано с потоками), что не имеет значения в вашем коде. Stick с my.

Вы могли быть в состоянии сделать:

my $db_handle : shared; 

А потом в теме:

$db_handle = DBI->connect($dsn, $user, $password); 

Но имейте в виду, вы не можете быть уверены, когда это будет полной, так что это очень важно проверить, прежде чем пытаться использовать его в другом потоке.

+0

но он все еще зависает при подключении к удаленной БД, я просто сделал то, что вы сказали мне, я только что изменил, мой $ connect: shared – Muskovitz

3

См. PerlMonks: Tk не является потокобезопасным.

  1. Создать тему перед созданием любых виджетов Tk.
  2. Не трогайте любые объекты Tk из потока, используйте общие переменные для связи.
+0

эй! пожалуйста, дайте мне пример кода, чтобы я мог построить для него небольшой алгоритм, потому что я попытался сделать $ connect как общую переменную, но он все равно зависает, ожидая завершения соединения. – Muskovitz

+0

@Muskovitz: связанная страница уже содержит рабочий код. – choroba

+0

замечательные ссылки perlmonks очень полезны для perl/tk & thread starters! – Muskovitz

Смежные вопросы