Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在perl plack应用程序中实现非阻塞响应?_Perl_Nonblocking_Plack_Anyevent - Fatal编程技术网

如何在perl plack应用程序中实现非阻塞响应?

如何在perl plack应用程序中实现非阻塞响应?,perl,nonblocking,plack,anyevent,Perl,Nonblocking,Plack,Anyevent,我正在尝试使用(即plack应用程序)编写一个基于perl的Web服务器。 我希望通过运行一些可能耗时的子例程来响应某些数据的请求(来自网页上的ajax调用),该子例程生成数据,然后将其转换为JSON字符串以返回到客户端网页 您可以在此处看到我的服务器的精简测试版本: 该示例显示了我当前实现所面临的问题;使用来执行非阻塞部分会导致截断“大”json响应 这篇文档将完美地回答我的问题(并更好地解释我要做的事情):。。。如果它完成了。我只是缺少了“正确”的非阻塞方式,而不是使用AnyEvent::F

我正在尝试使用(即plack应用程序)编写一个基于perl的Web服务器。 我希望通过运行一些可能耗时的子例程来响应某些数据的请求(来自网页上的ajax调用),该子例程生成数据,然后将其转换为JSON字符串以返回到客户端网页

您可以在此处看到我的服务器的精简测试版本: 该示例显示了我当前实现所面临的问题;使用来执行非阻塞部分会导致截断“大”json响应


这篇文档将完美地回答我的问题(并更好地解释我要做的事情):。。。如果它完成了。我只是缺少了“正确”的非阻塞方式,而不是使用
AnyEvent::ForkManager
,这看起来有点像黑客。

因此,从评论中可以看出,我对您使用的东西了解不够,无法给出具体的响应,但可以提供一些通用的东西

将线程用于Perl脚本的“异步”部分:

#!/usr/bin/perl

use strict;
use warnings;

use threads;
use Thread::Queue; 

my $input_q = Thread::Queue -> new();
my $success_q = Thread::Queue -> new(); 
my $failure_q = Thread::Queue -> new();

my $thread_count = 4; 

sub spinoff_thread {
    while ( my $target = $input_q -> dequeue() )
    {
       #do something to $target
       my @results = `ping -c 10 -i 1 $target`;
       if ( $? ) { 
           $failure_q -> enqueue ( $target );
       }
       else {
           $success_q -> enqueue ( $target );
       }
    } 
}

#main bit

for ( 1..$thread_count ) {
    my $thr = threads -> create ( \&spinoff_thread );
}

foreach my $server ( "server1", "server2", "server3", "server4", "server5" ) {
  $input_q -> enqueue ( $server );
}

$input_q -> end(); #will cause threads to 'bail out' because that while loop will go 'undef'); 

 #wait for threads to complete. 
foreach my $thr ( threads -> list() ) {
   $thr -> join();
}


print "Fail:\n", join ("\n", $failure_q -> dequeue() ), "\n";
print "Success:\n"; join ( "\n", $success_q -> dequeue() ), "\n";
关键点在于,线程基本上是子例程,可以使用队列来回传递内容
end
队列是一种处理通知线程终止的好方法——当然还有其他方法

我个人会用。从其概要中:

use Net::Async::HTTP::Server::PSGI;
use IO::Async::Loop;

my $loop = IO::Async::Loop->new;

my $httpserver = Net::Async::HTTP::Server::PSGI->new(
   app => sub {
      my $env = shift;

      return [
         200,
         [ "Content-Type" => "text/plain" ],
         [ "Hello, world!" ],
      ];
   },
);

$loop->add( $httpserver );

$httpserver->listen(
   addr => { family => "inet6", socktype => "stream", port => 8080 },
   on_listen_error => sub { die "Cannot listen - $_[-1]\n" },
);

$loop->run;

显然,这个特别小的示例没有演示任何异步功能,但是您可以完全访问所有
IO::Async
系统,以便延迟并在稍后做出响应。

我不太清楚您试图实现非阻塞的目的是什么。我不能轻易给出Plack等的细节,但如果是文件或套接字IO。。。有很多标准的解决方案。理想情况下,我正在寻找一种通用的方法,它可以接受任何黑盒子例程并无阻塞地运行它。但如果这不可能,那么其中一个子例程耗时的一个例子就是通过它的REST接口查询另一台服务器?好啊您可能希望查看线程和线程,或者使用
fork()
使用哪种线程取决于数据的紧密耦合程度-线程有利于与信号量和队列共享内存-在线程之间来回传递数据相对容易。分叉可能会提高性能,但前提是以后不需要同步。在分叉的进程之间来回传送数据是一件痛苦的事情。请注意——如果你不小心,并行处理将是一个痛苦的世界——你可能会创建一些非常有趣的bug。是的,我当前的实现是通过异步fork(AnyEvent::ForkManager)实现的,但我希望这是一件标准的事情,人们会有一些具体的代码示例来说明这类事情通常是如何完成的。我非常喜欢在可能扔掉它并使用模块之前滚动自己的代码。考虑到这一点,我可以提供一个如何使用队列在perl中执行线程的示例。