Domanda

Diciamo che ho una discussione:

sub     new {
        my      $class = shift;
        my      $self = ref $class || $class;

        bless { 'read_set'  => IO::Select->new,
                'write_set' => IO::Select->new,
                'error_set' => IO::Select->new }, $self;
}


sub     start {
        my      $self = shift;

        $self->{'thread'} = threads->create(\&worker_thr, $self);
        $self->{'thread'}->detach;
}

sub     worker_thr {
         my      $self = shift;

         while(1) {
                 my($read_active, $write_active, $error_active) = 
                    IO::Select->select(
                            $self->{'read_set'},
                            $self->{'write_set'},
                            $self->{'error_set'}, 
                            undef
                    );
         }

}       

Dato che non ho fornito alcun timeout per select () e si blocca indefinitamente fino a quando non viene rilevata attività su uno dei set di descrittori (bene, "gestisci"), cosa succede se un altro thread modifica il contenuto dei set (ad es. aggiunge un nuovo socket per il polling)?

È implementato in modo sicuro per i thread, rispetto all'implementazione dei thread Perl POSIX?

In caso contrario, suppongo di poter attaccare la chiamata di blocco select () in un blocco con il suo ambito e bloccare i set o, più chiaramente, i dati dell'intero pacchetto. Qual è il modo migliore per riattivare select () per tornare da un altro thread in modo che il contenuto dei set possa essere manipolato? Segnale specifico del thread? Semaforo? Suggerimenti benvenuti.

Grazie mille!

Modifica: Bene, segnale " specifico del thread " è fuori. Come spiegato qui ( http://perldoc.perl.org/threads.html ): " ; Di conseguenza, l'invio di un segnale a un thread non interrompe l'operazione su cui il thread sta attualmente lavorando: il segnale verrà attivato dopo che l'operazione corrente è stata completata. Ad esempio, se il thread è bloccato su una chiamata I / O, l'invio di un segnale non causerà l'interruzione della chiamata I / O in modo tale che il segnale venga attivato immediatamente. & Quot;

Questo mi lascia ancora da chiedermi come dovrei gestire il problema di svegliare select () in un thread se voglio che si blocchi indefinitamente invece di tornare dopo un timeout fisso.

È stato utile?

Soluzione

Per impostazione predefinita, i thread perl non condividono alcun dato, quindi se un thread cambia i suoi set non influenzerà l'altro. Quindi sì, è thread-safe, ma probabilmente non fa quello che vuoi che faccia.

Se vuoi davvero riattivare un altro thread o processo che sta bloccando su una selezione, una soluzione semplice è aggiungere una pipe alla sua coda di lettura. Puoi quindi riattivarlo scrivendo un byte in quella pipe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top