0

cgi パラメーターで指定されている「デバイス」に基づいて、open2() の背後に隠された一連のインタープリターにリクエストが送信される Web サーバーを作成しようとしています。

問題は、マルチスレッドにしたいのですが、各デバイスに関連するイベントキューを追跡するために使用しているハッシュが、リクエストごとに作成された新しいデバイスを記憶していないことです: 以下のサーバーは、この種のもの:

Did not find default-device in (alreadyThere)...

Added default-device with Sun Oct 27 20:43:35 2013 to alreadyThere, default-device
Now... does (alreadyThere, default-device) persist for the next request?

スクリプトは次のとおりです。

#!/usr/bin/perl -w
use strict;
use threads;
use threads::shared;
use base qw(Net::Server::HTTP);

our $monkeys = shared_clone({ alreadyThere => { 'a' => 'b' } });

sub process_http_request {
    require CGI;
    my $cgi = CGI->new;
    my $device = $cgi->param('device') || 'default-device';

    print "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n<pre>";
    unless (exists $monkeys->{$device}) {
        print "Did not find $device in (".join(", ", sort keys %$monkeys).")...\n";
        lock $monkeys;
        unless (exists $monkeys->{$device}) {
            my $t = localtime;
            $monkeys->{$device} = $t;
            print "\nAdded $device with ".$t." to ".join(", ", sort keys %$monkeys);
        } else {
            print "\nSurprise device... ".$device;
        }
    } else {
        print "\nFound device... ".$device;
    }

    print "\nNow... does (".join(", ", sort keys %$monkeys).") persist for the next request?</pre>";
}

__PACKAGE__->run(port => 8080);

それは $t ビットではありません - 以前は shared_clone({ id => $t }) でした。

4

3 に答える 3

2

異なる要求は、スレッドではなく、異なるプロセスによって処理されます。

Net::Server にはマルチスレッドの「パーソナリティ」[1]がないため、別の共有メカニズムを使用する必要があります。


ノート:

  1. 「近い将来、『スレッド』パーソナリティを追加したいと考えています」
于 2013-10-27T22:51:06.933 に答える
0

池上の答えに基づいて、この追加のコードを使用して、「スレッド化された」パーソナリティを偽造して、いくつかの成功を収めようとしています(および「open3」の誤動作に関するいくつかの問題):

sub default_server_type { 'Single' }

sub loop {
  my $self = shift;
  while( $self->accept ){
    async {
        $self->run_client_connection;
    };
    last if $self->done;
  }
}
于 2013-10-28T13:16:34.523 に答える
0

a) より高レベルで使いやすい Plack の代わりに Net::Server::HTTP を使用する理由はありますか?
b) 最近、このような問題を解決する必要があり、イベントベースの httpd とAnyEvent (またはより高い抽象化、Coro ) を使用することにしました。コードのドロップイン置換が必要な場合、またはTwiggyFeersumなどの大量の既製の AnyEvent ベースの httpds が必要な場合は、 Net::Server::Coroがあります。

于 2013-10-28T17:27:09.267 に答える