Hi,
this is more a question of understandind as my solution is running, but with warning, otherwise it won't run.   Of course deleting 'use warnings' it will dissapear that but I still don't know what happens.

I need a chat server to exchange the results of a program running on several different pc.   I found a nice solution some time ago of Patrick Haller, but it wasn't buffered and I don't want that the client gets back what he has just sent and finally the Writer did not die when the socket was broken.   Originally the line that should cause the Writer to die was

print $socket $line,$EOL or die;
  1. Obviously the Writer can't reconize that the socket is broken - why?
  2. Below the loop of the Reader I push into @chat a line that the Writer (which has the same ID as the Reader) should reconize to die. This works (ONLY?) if I do NOT put a lock(@chat) in the line before I push into @chat?
    Will this cause weired problems sudddenly?
  3. General question: lock($var) is meant to lock the variable $var for ALL
    the OTHER threads to do s.th with this $var until it is 'broadcasted' - correct?
  4. Is there a 'more' correct version for the Writer to die, if the socket of the Client is broken.
  5. Finally. In the detached Writer and Reader $$ always gives back the PID of the Parent, that was detaching both threads. Is there way to geth the PID of the childs in this way (not using fork ...)

Well here is the code of the important parts. (If s.o. is interested I can send the whole prg)

#!/usr/bin/perl use strict; use warnings; use threads; # pull in threading routines use threads::shared; # and variable sharing routines use IO::Socket::INET; # and rock the sock et use File::Temp qw/ :POSIX /; our @chat:shared = (); our $EOL = "\r\n"; # signal for the writer to die: our $kill = 'my Socket broke'; $SIG{PIPE} = 'ignore'; sub ignore { ; } my $server = IO::Socket::INET->new( LocalPort => 1234, Type => SOCK_STREAM, Reuse => 1, Listen => 10 ) or die $!; while (my $client = $server->accept()){ tmpnam() =~ /tmp\/(.+)/; # use tmp-file name for the IDs my $r = threads->new(\&Reader::run, client => $client, "ID","$1"); $r->detach(); my $w = threads->new( \&Writer::run, client => $client, "ID", "$1" ); $w->detach(); } ##### package Reader; use threads; use threads::shared; sub new {..} sub run { my $self = Reader->new(@_); my $socket = $self->{client}; my $l; while(defined ($l = <$socket>) ){ lock(@chat); push @chat, "$self->{ID}\t$1"; cond_broadcast(@chat); } # this is the only way that I've found to make th Writer die .. # Now let the Writer know to stopservice and die: # AND HERE is MY PROBLEM: # with lock(@chat) before push the Writer won't get it, won't die! # but cond_broadcast(@chat) causes the warning.. push @chat, "$self->{ID}\t$kill"; cond_broadcast(@chat); print "Reader $$: $self->{ID} will die, bye\n"; } ##### package Writer; use threads; use threads::shared; sub new { .. } sub run { my $self = Writer->new(@_); my $socket = $self->{client}; my $ID = $self->{ID}; # easier to use in regExpr. while( "@chat" !~ /$ID$kill/ ) { # to leave the loop to die lock(@chat); cond_wait(@chat); foreach (@chat) { $_ =~ /(.+?)\s(.+)$/; print $socket $2,$EOL if ( $1 ne $ID && $2 ne $kill); # this does not work: print $socket $2, $EOL or die; } } print "Writer $$: $ID will die, bye\n"; }

janitored by ybiC: Balanced <readmore> tags around code section, format tweaks for legibility. Pleasantly surprised to see anonymonk use <code> tags.


In reply to thread:shared by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.