johnnywang has asked for the wisdom of the Perl Monks concerning the following question:

I'm running into problems using Class::DBI with threads. My setup is very simple: first use Class::DBI to retrieve a set of objects from database, then for each such object, I'll start a new thread to process it. The following is a stripped-down version (just retrieve one object, and start one thread):
use strict; package MyClass; use base 'Class::DBI'; __PACKAGE__->set_db('Main','dbi:mysql:test', 'test','test'); __PACKAGE__->table('MYCLASS'); __PACKAGE__->columns(Primary=>qw/ID/); __PACKAGE__->columns(Others => qw/NAME/); package main; use threads; my $s = MyClass->retrieve(1); threads->new(\&test, $s)->join(); print "done\n"; exit 0; sub test{ my $o = shift; print $o->name,"\n"; }
I got the following errors:
thread failed to start: DBD::mysql::db FETCH failed: handle 2 is owned + by thread 22432c not current thread 1b1e014(handles can't be shared +between threads and your driver may need a CLONE method added) at C:/ +Perl/site/lib/Ima/DBI.pm line 316. Attempt to free non-existent shared string 'test~~test~~test~~AutoComm +it~~ChopBlanks~~FetchHashKeyName~~PrintError~~RaiseError~~RootClass~~ +ShowErrorStatement~~Taint~~Username~~dbi_connect_method~~1~~1~~NAME_l +c~~0~~1~~DBIx::ContextualFetch~~1~~1~~test~~connect_cached' during gl +obal destruction. Free to wrong pool 1b24430 not 222770 during global destruction.
The first error is instructive, but I'm not sure how to fix it, can one pass the objects retrieved via Class::DBI to other threads? by the way, line 316 of DBI.pm is the "unless" line in the following:
sub _mk_db_closure { my ($class, @connection) = @_; my $dbh; return sub { unless ($dbh && $dbh->FETCH('Active') && $dbh->ping) { $dbh = DBI->connect_cached(@connection); } return $dbh; }; }
I'm more at a loss to the second one, it seems to be some db connection string, but who's doing the destruction and garbage collection here? Thanks.

Replies are listed 'Best First'.
Re: threading problem with Class::DBI
by perrin (Chancellor) on Sep 23, 2005 at 01:00 UTC
    Threads and DBI don't seem to work at this point. Either just read the data from the objects into a hash and pass that to the threads instead of objects, or use forking instead of threads.
Re: threading problem with Class::DBI
by pg (Canon) on Sep 23, 2005 at 00:57 UTC

    You cannot, as of Perl 5.8.7, blessed objects are not visible to other threads.

Re: threading problem with Class::DBI
by aufflick (Deacon) on Sep 23, 2005 at 05:14 UTC