Reputation: 23729
I used this article: http://www.perlmonks.org/?node_id=594175 to write code, combining DBI with fork. It works on Linux, but doesn't work on Windows XP. I am using Active state Perl v5.10.0 MSWin32-x86-multi-thread, DBD::mysql v4.011.
On Linux Perl v5.16.1 i486-linux-thread-multi DBD::mysql v4.021.
Code. dbi_fork.pl:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
require "mysql.pl";
my $dbh = connect_mysql();
if (fork()) {
$dbh->do("UPDATE articles SET title='parent' WHERE id=1");
}
else {
my $dbh_child = $dbh->clone();
$dbh->{InactiveDestroy} = 1;
undef $dbh;
$dbh_child->do("UPDATE articles SET title='child' WHERE id=2");
}
mysql.pl:
sub connect_mysql
{
my $user_db = 'user';
my $password_db = 'secret';
my $base_name = 'test';
my $mysql_host_url = 'localhost';
my $dsn = "DBI:mysql:$base_name:$mysql_host_url";
my $dbh = DBI->connect($dsn, $user_db, $password_db) or die $DBI::errstr;
return $dbh;
}
1;
articles table:
DROP TABLE IF EXISTS `articles`;
CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of articles
-- ----------------------------
INSERT INTO `articles` VALUES ('1', 'title1');
INSERT INTO `articles` VALUES ('2', 'title2');
On Windows it gives an error:
$ perl ./dbi_fork.pl
DBD::mysql::db clone failed: handle 2 is owned by thread 2344b4 not current
thread 1a45014 (handles can't be shared between threads and your driver may
need a CLONE method added) at ./dbi_fork.pl line 14.
How to fix?
Upvotes: 0
Views: 890
Reputation: 385764
There's no such thing as fork
on Windows. It's a feature specific to unix systems. Perl emulates it using threads on Windows, and this is causing problems.
Rather than trying to recreate an existing connection, simply create the connections in the task.
In other words, use
if (fork()) {
my $dbh = connect_mysql();
$dbh->do(...);
} else {
my $dbh = connect_mysql();
$dbh->do(...);
}
Upvotes: 4
Reputation: 23729
Here is the solution - every thread creates it's own connection:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
require "mysql.pl";
if (fork()) {
my $dbh = connect_mysql();
$dbh->do("UPDATE articles SET title='parent' WHERE id=1");
}
else {
my $dbh = connect_mysql();
$dbh->do("UPDATE articles SET title='child' WHERE id=2");
}
Upvotes: 2