Perl 5.8.0 & fork & listen->accept

Pagina: 1
Acties:

  • Knifter
  • Registratie: Februari 2003
  • Laatst online: 15-04 16:52
Hoi,

Ben nieuw hier, dus tis mn eerste post.

Maar ik heb sinds kort perl 5.8.0 draaien op mn freebsd 4.7 systemen en sindsdien heb ik erg vage problemen met signals en fork's.

Heeft er hier iemand perl 5.8.0 draaien?
Het volgende stukje is het probleem geisoleert:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/perl

$|++;
use IO::Socket;

$listenport=50;
my $listen=IO::Socket::INET->new(LocalPort => $listenport,
                              Proto => "tcp",
                              Type => SOCK_STREAM,
                              Reuse => 1,
                              Listen => 0 ) or die "Could't set up server on port $listenport\n";

sub REAPER
{
        $waitedpid = wait;
        # loathe sysV: it makes us not only reinstate
        # the handler, but place it after the wait
        $SIG{CHLD} = \&REAPER;
}
sub REAPER2 {
        1 until (-1 == waitpid(-1, WNOHANG));
        $SIG{CHLD} = \&REAPER;
}; #End REAPER

$SIG{CHLD} = \&REAPER2;

while($conn=$listen->accept())
{
        $pid=fork();
        if($pid)
        {
                print "FORKED: Server goes on...pid: $pid\n";
                print "M";
                sleep(1);
                next;
        } else {
                print "FORKED: Client goes on....pid: $pid\n";
                $i=5;
                while($i--)
                {
                        print "C";
                        sleep(1);
                };
                close($conn);
                sleep(1);
                print "Exit";
                exit(0);
        };
};



Wat er met dit stukje gebeurt is het volgende:
Process wacht op connectie, en als het een connectie krijgt forked ie. de child wacht 5(6... ja) sec en gaat er gewoon uit.
De parent gaat na een 1 sec echter al weer terug naar $listen->accept() en wacht daar op een nieuwe verbinding. En nu komt ie: op het moment dat de _laatste_ child afsluit komt de parent uit $listen->accept() en doet een 'normale' exit. Niet de bedoeling dus...
Als ik de $SIG{CHLD} er uit haalt gebeurt dit niet. Als ik REAPER2 ipv REPEAR gebruik gebeurt het ook. En uiteraart wil ik wel een REAPER omdat de orphans de boel wel overlaten lopen anders...
Perl 5.005xxx en Perl 5.6.1 hebben hier beide totaal geen last van.

Ik vraag me dus ook af of er mogelijk iets mis is gegaan met de threads of signal libs van perl tijdens het compileren.

Grt Tijs

p.s. Ik kon geen perl forum vinden (!duits aub), dus post ik hem hier. als iemand er wel een weet -> graag....

  • tomato
  • Registratie: November 1999
  • Niet online
Misschien is het relevant om te weten dat er nogal wat is veranderd in de threads en IO implementaties van 5.8.

  • Knifter
  • Registratie: Februari 2003
  • Laatst online: 15-04 16:52
Thxn, gelezen. Maar kan nog niets vinden wat dit gedrag verklaart. Intussen heb ik ook gemerkt dat de sleep() functie nooit meer wakker wordt als het process in de background draaid.

Ik ga perl opnieuw compiler met de ithreads support, dan ga ik zowiezo over op threads.

Grt Tijs

  • Juup
  • Registratie: Februari 2000
  • Niet online
perlmonks.org is een engelstalige en leading perl community/forum site.

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:08
Je probleem kan ik niet direct oplossen, maar ik weet wel dat bij mij vrijwel alle SysV tests voor Perl (zowel 5.6 als 5.8) falen onder FreeBSD 5.0. Het zou dus gewoon een stomme bug kunnen zijn.

Ik snap trouwens niet wat je reaper verondersteld wordt te doen, en hoe je er zombie processen mee voorkomt. Verder lijkt me dat je in REAPER2 zichzelf wil herinstalleren, en niet de andere REAPER (zoals je nu doet).

Tenslotte snap ik niet waarom je een wait call in je reaper functie hebt staan. Waar wacht je nu eigenlijk op? Je child is al afgesloten, anders zou 'ie nooit aangeroepen worden. Mij lijkt dat je juist die wait daar niet wil hebben, maar mijn Perl kennis is nogal gebrekkig.

Als ik gelijk heb, en die wait call hoort daar niet, dan kan ik me voorstellen dat als een tweede child exit, er geen signal geinstalleerd is, en je accept dus onderbroken wordt.

[ Voor 1% gewijzigd door Soultaker op 15-02-2003 15:42 . Reden: reaper is echt een kutwoord om te typen :P ]


  • Knifter
  • Registratie: Februari 2003
  • Laatst online: 15-04 16:52
Soultaker:

Dat is pecies wat de repear doet. ([flameprotect]zover ik het juist heb begrepen[/flameprotect])
Als een child klaar is. krijgt de parent dus de SIGCHLD. die synced (dat is nou eenmaal iets wat meerdere procs doen :) ) dmv 'wachten' zodat de return value van het child uitgelezen kan worden, als dat gebeurt is kan het child dus opgeruimt worden. vandaar 'wait', wachten tot het 'wees' child in sync is voor returnvalue. Hierna dient de SIGCHLD opnieuw geinstalled te worden, ik denk dat dit is om de signal interrupts te her-enablen, zodat je er niet meer te gelijk kan krijgen.


Jaaap:
thxn a lot. Ik ben er nu aan het kijken, had hem zelf nog niet gevonden.
Pagina: 1