[C++/linux] forked child killen

Pagina: 1
Acties:

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
K'ben net begonnen met een servertje, geschreven in C++ (met nog wat C functie's ertussen) en nog geen echt OO gebruik maar dat komt wel zodra ik het protocol en de rest ga implementeren.

Op zicht doet hij al wat hij moet doen, maar nu fork'ed hij voor elke connectie een child die blijft leven nadat de client gedisconnect is, nu dacht ik met vanuit de code zelf een pid te killen (kill(mypid, SIGCHLD);) dat de parent niet mee gekilled zou worden, dit is helaas niet waar, of toch niet op deze manier.

Dit krijg ik dus na 3 connectie's.
code:
1
2
3
4
blacky   27095  0.0  0.5  1680  564 pts/1    S    14:46   0:00  |           \_ ./server 4444
blacky   27096  0.0  0.0     0    0 pts/1    Z    14:46   0:00  |               \_ [server <defunct>]
blacky   27099  0.0  0.0     0    0 pts/1    Z    14:50   0:00  |               \_ [server <defunct>]
blacky   27100  0.0  0.0     0    0 pts/1    Z    14:51   0:00  |               \_ [server <defunct>]


The source
Er staat wat uitgecommente code in wat ik al geprobeerd heb,
- In de child zelf z'n pid opvragen en zelf afschieten, gevolg partent stierf mee
- De child z'n pid laten returnen naar de parent en hem daar kill'n

Heb wel intressante dingen gevonden over wait() maar lijkt niet wat ik nodig heb.


Normaal lijkt exit() hier wel geschikt, dat was het eerste wat ik probeerde maar dan returned g++ een error:
server-main.cpp: In function `int spawn_connection(int, sockaddr_in)':
server-main.cpp:195: `exit' cannot be used as a function

If it ain't broken it doesn't have enough features


  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
De server die je source host is offline...

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
Limhes schreef op 16 november 2002 @ 15:32:
De server die je source host is offline...
sorry, was vergeten dat poort 80 enkel voor binnen openstaat & 4000 voor de buitenwereld is.

If it ain't broken it doesn't have enough features


Verwijderd

Je processen zijn wel dood! Het zijn alleen zombies. Deze worden pas door je operating system opgeruimt als het het parent process voldoende kans gegeven heeft de exit status van de childs op te vragen.

Het is verstandig om zombies expliciet op te ruimen, vooral als je er nogal veel maakt. Zie wait(2).

Verwijderd

Je netwerk-code is redelijk maar je forked veel te veel processen; lees de manual van fork() eens door. Herschrijf spawn_connection() tot iets als handle_connection() en fork geen nieuwe processen in die functie, je forked immers al een child-process voor elke binnenkomende connectie in je main().

Verder zitten er nog wat slordigheidsfoutjes in; zo is bv. while(!exit || i == maxruns) natuurlijk een behoorlijk stinkende constructie, zou dat niet while(!exit && i < maxruns) moeten zijn? (i daarbij op 0 initialiseren voor je die lus in duikt is ook handig).

edit:
Toevoeging

Als je children wilt killen vanuit de parent dan doe je dat met kill(childpid, SIGTERM), en niet met SIGCHLD. SIGCHLD is een signal dat de parent krijgt wanneer een child dood gaat of gestopt wordt (een beetje server installeert daarom een signal handler voor SIGCHLD).

En natuurlijk moet je wel gebruik maken van wait() of waitpid() in je parent om op je ge-exite child processen te wachten. Anders maak je idd. zombies, zoals duidelijk in de manual staat.

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
Ok beiden bedankt, net wat geprutst het zombie process word al afgesloten, nog een beetje prutsen en de basis werkt zoals het hoort, af en toe nog wat slordigheidjes, code cleanup komt meestal zodra ik een werkend model heb, zal er voortaan wat meer rekening mee houden :)

[edit]
Volgens mij had je trouwens ook een beetje een verkeerd beeld over waarom die fork() nog in spawn_connection stond ... het is de bedoeling dat alles afgehandeld zal worden in de swawn_connection (protocol o.a.) en er zouden nooit andere dingen daaruit worden gestart via fork().

Ik weet niet of 1 child per connectie performance gewijs goed is maar ik schat op max 30-40 tal gebruikers.

If it ain't broken it doesn't have enough features


Verwijderd

Ik weet niet of 1 child per connectie performance gewijs goed is maar ik schat op max 30-40 tal gebruikers.
Je wilt je nick eer aan doen (de software versie daarvan tenminste) en je child processen hergebruiken bij het afhandelen van verbindingen. Een proces spawnen is onder unix vrij goedkoop, maar hergebruiken van een bestaand proces is nog altijd goedkoper...

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
Ik ben geen webserver aan het schrijven hoor ;)
het gaat om instant messaging, waar vooral gekeken word naar icq, dus het is niet dat een gebruiker een request doet, hij zijn response krijgt en er voor de rest niets moet gebeuren tot de volgende pagina die hij opvraagt.

Een gebruiker zal gevalideerd worden, inloggen, en dan vaak informatie ontvangen van de server (o.a. status veranderingen van mensen in zijn contactlist etc).

If it ain't broken it doesn't have enough features


Verwijderd

offtopic:
Jammer :)
Webservers (of eigenlijk het hele idee van servers zonder state en veel heel korte requests) zijn best leuk om je op uit te leven. Ik kwam er pas achter dat IIS tegen de 600(!) requests per seconde af kan handelen (op een P4 1400)... dat lukt je dus bijvoorbeeld echt niet als je voor elk request een proces start ofzo.

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
Ik ben er toch nog niet helemaal uit.

K'heb sinds de dag van dit topic echt al enorm veel geprobeerd met wait(), waitpid() & kill()

Met wait() heb ik al successvolle resultaten gehad dat hij de zombie thread opruimt, maar zoals de functie naam al doet vermoeden wacht hij ondertussen en kan er in de main server thread niets gebeuren (maw geen andere connectie's accepteren voor die afgehandeld is)

De bedoeling is, pers A connect, er word een process geforkt om die connectie van pers A af te handelen tot die disconnect. Pers B connect ook (terwijl pers A geconnect is) krijgt ook een child, pers A disconnect en die pers A z'n thread word opgekuist.

Ik heb alle mogelijke combinatie's en plaatsen afgelopen maar dichter dan de wait() waarbij pers B niet kan inloggen zolang pers A geconnect is ben ik niet geraakt.

K'heb het gevoel dat ik iets over het hoofd zie eerlijk gezegd, o.a. dingen als process zichzelf laten beeindigen na een exit (einde van handle_connection() of op de return van iets van handle_connection() leidde ook tot niets)

nieuwe source

If it ain't broken it doesn't have enough features


Verwijderd

Je bent verplicht te wait()en op een child proces. Zo'n wait call is blocking, TENZIJ er al een child is afgesloten. Zodra er een child proces zichzelf beeindigt krijgt je parent proces een SIGCHLD. Je wilt dus aan je programma een signal handler toevoegen voor SIGCHLD en daarin wait() aanroepen. Dan zal je wait call dus non-blocking zijn EN je bent van je zombies af.

Mocht je serieus aan de slag willen met UNIX programmering dan kan ik je 'Advanced programming in the UNIX environment' van Stevens aanraden. (ISBN: 0-201-56317-7)...

  • Apache
  • Registratie: Juli 2000
  • Laatst online: 17-08 14:28

Apache

amateur software devver

Topicstarter
Bedankt Qlone, dat was idd een goede oplossing.

En ik wil idd serieus aan de slag met UNIX programming dus ook bedankt voor die tip, heb ik meteen iets voor onder de kerstboom ;)

If it ain't broken it doesn't have enough features

Pagina: 1