Я использовал эту статью: http://www.perlmonks.org/?node_id=594175 написать код, объединив DBI с вилкой. Он работает в Linux, но не работает в Windows XP. Я использую Active State Perl v5.10.0 MSWin32-x86-multi-thread, DBD :: mysql v4.011.DBI и fork не работают на Windows
В 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.
Как исправить?
** (1) ** Вы не можете сравнить поведение из Версия для Windows с версией Linux; здесь слишком много переменных. Вы можете уменьшить количество переменных, установив perl5.16 в поле XP (например, [Strawberry Perl] (http://strawberryperl.com/)) и установив ту же версию DBD :: mysql. ** (2) ** В любом случае Windows не имеет встроенной 'fork'. Вместо этого он эмулируется с помощью потоков. Похоже, что проблему можно обойти, клонируя дескриптор перед «вилкой» и с каждой стороны закройте неиспользованный дескриптор. Или ребенок запускает 'connect_mysql' заново для получения второго дескриптора. – amon
@amon: Вы должны опубликовать это как ответ. – Borodin