J'essaye d'écrire le code de Perl qui fait la communication bidirectionnelle sur un socket Unix. Il doit faire les choses suivantes: CodeMessage de socket bloque jusqu'à ce que le thread se termine en Perl
- client envoie une requête sur la prise
- code lit la requête
- Server effectue toutes les actions qui devrait se produire immédiatement
- Server crée un nouveau thread à faire des actions supplémentaires qui peuvent prendre beaucoup de temps
- Server envoie une réponse sur la prise
- le client reçoit une réponse
- Le nouveau thread continue à fonctionner après que la réponse a été envoyée
J'ai obtenu la plupart de ceci pour fonctionner maintenant, mais avec un problème. Les étapes 1 à 5 fonctionnent correctement, mais à l'étape 6, le client est incapable de lire la réponse tant que le thread n'est pas passé. (même si la réponse a été envoyée plus ou moins immédiatement) Une idée de ce que je fais mal? J'utilise Perl 5.10.1 sur Lucid Ubuntu.
Voici un exemple:
Code client:
#!/usr/bin/perl
use strict;
use Socket;
my $socket_name = 'catsock';
my $client_message = "Hello server, this is the client.";
my $SOCK;
socket($SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
connect($SOCK, sockaddr_un($socket_name)) or die "connect: $!";
$| = 1, select $_ for select $SOCK; # turn on autoflush
print $SOCK $client_message; # send the message
shutdown($SOCK,1); # finished writing
print "sent: $client_message\n";
my $server_message = do { local $/; <$SOCK> }; # get the response
print "recieved: $server_message\n\n";
Code Serveur
#!/usr/bin/perl
use strict;
use Socket;
use threads;
use threads::shared;
sub threadfunc
{
print " waiting 5 seconds in new thread...\n";
sleep(5);
print " exiting thread...\n\n";
}
my $server_message = "Hello client, this is the server.";
my $socket_name = 'catsock';
my $SERVER;
my $CLIENT;
socket($SERVER, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
unlink($socket_name);
bind($SERVER, sockaddr_un($socket_name)) or die "bind: $!";
chmod(0660, $socket_name);
listen($SERVER, SOMAXCONN) or die "listen: $!";
print "server started on $socket_name\n\n";
while(1) {
accept($CLIENT, $SERVER);
my $client_message = do { local $/; <$CLIENT> }; # grab entire message
print "recieved: $client_message\n";
print "creating new thread...\n";
my $thr = threads->create(\&threadfunc);
$thr->detach();
print $CLIENT $server_message; # send the response
print "sent: $server_message\n\n";
close $CLIENT;
}
Quand je lance cela, les choses suivantes se produisent:
- Le client envoie "Bonjour serveur, c'est le client."
- Server reçoit le message du client
- Server crée un nouveau thread
- Server envoie "Bonjour client, c'est le serveur."
- Le client doit recevoir le message maintenant, mais ce n'est pas le cas.
- fil Nouveau sur le serveur dort pendant 5 secondes
- des sorties de discussion
- Maintenant le client reçoit le message du serveur, même si il a été envoyé il y a 5 secondes. Pourquoi?
définir '$ CLIENT' pour autoflush après l'accepter? –
Est-il possible que le thread serveur bloque dans la méthode $ thread-> detach et par conséquent l'écriture sur $ CLIENT ne s'exécute pas jusqu'à ce que le thread de travail se termine? – feroze
@feroze - le thread supplémentaire maintient la connexion ouverte pendant 5 secondes (bien que je ne sache pas exactement comment - le thread a une copie privée de '$ CLIENT' et la connexion ne se ferme pas tant que toutes les copies ne sont plus en scope, peut-être), mais cela ne retarde pas l'écriture dans '$ CLIENT'. – mob