Question

Disons que j'ai un fil:

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
                    );
         }

}       

Comme je n'ai fourni aucun délai d'attente à select () et qu'il se bloque indéfiniment jusqu'à ce que l'activité soit détectée sur l'un des ensembles de descripteurs (bien, "handle"), que se passe-t-il si un autre thread modifie la contenu des ensembles (p. ex. ajoute une nouvelle prise pour interrogation)?

Est-il implémenté d'une manière thread-safe, par rapport à l'implémentation des threads Perl POSIX?

Sinon, je suppose que je peux coller l'appel select () bloquant dans un bloc avec sa propre portée et verrouiller les ensembles ou, plus proprement, les données complètes du paquet. Quel est le meilleur moyen de réveiller select () pour le renvoyer, à partir d'un autre thread afin que le contenu des ensembles puisse être manipulé? Signal spécifique au thread? Sémaphore? Suggestions bienvenues.

Merci beaucoup!

Modifier: "Signal" spécifique à un thread est dehors. Comme expliqué ici ( http://perldoc.perl.org/threads.html ): " ; En conséquence, l'envoi d'un signal à un thread ne perturbe pas l'opération sur laquelle le thread est en train de travailler: le signal sera traité une fois l'opération en cours terminée. Par exemple, si le thread est bloqué sur un appel d'E / S, lui envoyer un signal ne sera pas interrompu, de sorte que le signal sera immédiatement activé. "

Cela me laisse toujours à me demander comment je devrais gérer le problème de réveiller select () dans un fil de discussion si je souhaite le bloquer indéfiniment au lieu de revenir après un délai d'expiration déterminé.

Était-ce utile?

La solution

Par défaut, les threads Perl ne partagent aucune donnée. Par conséquent, si un thread change ses ensembles, cela n’affectera pas l’autre. Donc oui, il est thread-safe, mais il ne fait probablement pas ce que vous voulez.

Si vous souhaitez vraiment réactiver un autre thread ou processus bloquant une sélection, une solution simple consiste à ajouter un canal à sa file d'attente de lecture. Vous pouvez ensuite le réactiver en écrivant un octet dans ce tuyau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top