多线程 – Perl多线程程序偶尔崩溃

前端之家收集整理的这篇文章主要介绍了多线程 – Perl多线程程序偶尔崩溃前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Perl中编写了一个使用多线程的程序.我正在使用这个程序来了解Perl中多线程是如何实现的.

首先简要介绍一下程序打算做什么:它将从文本文件中读取一个URL列表,一次一个.对于每个URL,它将调用子例程(将URL作为参数传递),并向其发送HTTP HEAD请求.一旦接收到HTTP响应头,它将从响应中打印“服务器头”字段.

对于每个URL,它启动一个调用上述子例程的新线程.

问题:主要问题是程序有时会间歇性崩溃.其他时候运行正常.它似乎是不可靠的代码,我相信有一种方法使其可靠地工作.

代码

#!/usr/bin/perl

use strict;
use warnings;
use threads;
use WWW::Mechanize;
no warnings 'uninitialized';

open(INPUT,'<','urls.txt') || die("Couldn't open the file in read mode\n");

print "Starting main program\n";

my @threads;

while(my $url = <INPUT>)
{
    chomp $url;
    my $t = threads->new(\&sub1,$url);
    push(@threads,$t);
}

foreach (@threads) {
    $_->join;
}

print "End of main program\n";

sub sub1 {
    my $site = shift;
    sleep 1;
    my $mech = WWW::Mechanize->new();
    $mech->agent_alias('Windows IE 6');

    # trap any error which occurs while sending an HTTP HEAD request to the site
    eval{$mech->head($site);};
    if($@)
    {
        print "Error connecting to: ".$site."\n";
    }

    my $response = $mech->response();

    print $site." => ".$response->header('Server'),"\n";
}

问题:

如何使这个程序可靠地工作,零星崩溃的原因是什么?

调用线程对象的join方法的目的是什么?

根据下面链接的文档,它将等待线程执行完成.我正确地调用join方法吗?

http://perldoc.perl.org/threads.html

如果有上述代码中必须包含的良好的编程实践,请通知我.

是否需要在代码中单独调用sleep()或不需要?

在C中,调用CreateThread()之后调用Sleep()开始执行线程.

关于崩溃:当上述Perl代码意外和偶尔崩溃时,我收到错误消息:“Perl命令行解释器已停止工作”

崩溃的细节:

Fault Module Name:  ntdll.dll
Exception Code: c0000008

上述异常代码对应于:STATUS_INVALID_HANDLE

也许这对应于线程的无效句柄.

我的Perl安装细节:

Summary of my perl5 (revision 5 version 14 subversion 2) configuration:

Platform:
osname=MSWin32,osvers=5.2,archname=MSWin32-x86-multi-thread
useithreads=define

操作系统的详细信息:Win 7 Ultimate,64位操作系统.

希望这个信息足以找到问题的根本原因并纠正代码.

解决方法

你的代码没有错.可能是你的期望有点太高了.

Perl的线程通过在同一操作系统进程中创建多个解释器实例来实现.这将每个线程中的Perl代码与所有其他线程隔离(这是没有共享的).它不(或不能)做的是隔离不在perl控制下的代码.也就是说,具有以C编写的组件的任何模块.例如,快速查看WWW :: Mechanize表明,如果安装了zlib,则可以使用zlib进行压缩.如果这被使用,并且C代码不够线程安全,这可能是一个可能崩溃的问题.因此,如果您想确保您的Perl应用程序在线程下工作良好,则必须遍历所使用的所有模块(以及所有使用的模块),并检查它们是否具有非Perl部件,或者这些部件是线程安全的.对于大多数非常重要的程序,这是一个不合理的工作量(或者对您可以使用的CPAN模块有不合理的限制).

这可能是线程在Perl中不被使用的原因的很大一部分.

猜你在找的Java相关文章