0

我使用这篇文章:http ://www.perlmonks.org/?node_id= 594175 编写代码,将 DBI 与 fork 相结合。它适用于 Linux,但不适用于 Windows XP。我正在使用活动状态 Perl v5.10.0 MSWin32-x86-multi-thread, DBD::mysql v4.011。

在 Linux Perl v5.16.1 i486-linux-thread-multi DBD::mysql v4.021 上。

代码。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;

文章表:

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');

在 Windows 上,它给出了一个错误:

$ 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.

怎么修?

4

2 回答 2

4

fork在 Windows上没有这样的东西。这是 Unix 系统特有的功能。Perl 在 Windows 上使用线程来模拟它,这会导致问题。

无需尝试重​​新创建现有连接,只需在任务中创建连接即可。

换句话说,使用

if (fork()) {
    my $dbh = connect_mysql();
    $dbh->do(...);
} else {
    my $dbh = connect_mysql();
    $dbh->do(...);
}
于 2013-06-22T16:45:59.680 回答
2

这是解决方案 - 每个线程都创建自己的连接:

#!/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");
}
于 2013-06-22T17:58:51.533 回答