Zkouška 22.1.2013 - Kotal

Programování v UNIXu. Cvičení probíhá v laboratoři UNIX a poskytuje posluchačům průpravu v programování v jazyce C v prostředí UNIX.
petrbel

Zkouška 22.1.2013 - Kotal

Příspěvek od petrbel »

dnešní zadání - napište TCP server, který bude paralelně obsluhovat maximálně fixní (hadrcoded) počet klientů. Po připojení klient pošle na server string ve tvaru 'prog|arg1|arg2|...|argN|#'. Server spustí 'prog' s vyparsovanými argumenty a změří mu čas. Jak dlouho program běžel pošle (v milisekundách) zpátky klientovi. Pokud ale program neskončí do timeout, server ho zabije a jako výsledek pošle slovo TIMEOUT.

Program musí fungovat a nesmí obsahovat hrubé chyby (memory leaks, busy wait, stackoverflow etc... viz přednáška). Dále byste měli programovat ve vi nebo něčemu podobnému. Já to ladil v Sublime Text a to prostředí se mu líbilo - chce prostě, abyste si napsali sami Makefile a ladili to v terminálu a ne třeba v NetBeans. Nezapoměňte na cstyle (http://mff.devnull.cz/pvu/common/cstyle.pl), ale zas nijak zvlášt se to nehrotí. Warningy při kompilaci by se neměly vyskytovat (ani na -Wall u gcc).

Byli jsme tam 4, já odevzdával jako první po tři a třičtvrtě hodině, cca 20 min na ústní... Jak dopadli ostatní nevím - já měl dvojku.

Chce si to napsat testovací skriptík, který se bude spouštět: /tmp/wait.sh, protože u /bin/ls se timeoutu nedočkáte

Kód: Vybrat vše

#!/bin/sh

printf "sleep for %d
" $1
sleep $1
Usage (pro max 3 klienty):

Kód: Vybrat vše

terminal1$ ./a.out <port=12345> <timeout=5s>
terminal2$ echo -n '/tmp/wait.sh|2' | nc localhost 12345
terminal3$ echo -n '/tmp/wait.sh|4' | nc localhost 12345
terminal4$ echo -n '/tmp/wait.sh|7' | nc localhost 12345
terminal5$ echo -n '/tmp/wait.sh|3' | nc localhost 12345
na terminálu jedna by měl server vypisovat rozumné debug info (pozor! na strerr).
na terminálu 2 by mělo vypnout něco jako 2000 (ms)
na temrinálu 3 se vrátí 4000 (ms)
na terminálu 4 se vrátí TIMEOUT
nc se na terminálu 5 vůbec nepřipojí, protože server právě obsluhuje jiné tři klienty.

Šlo to řešit více způsoby (rozumné je udělat si server ve stylu paralelní accept(), kde je zadarmo omezení na počet klientů - já to dělal teda jinak a musel jsem použít semafor). Základní struktura programu je jasná, ale jak rozumně měřit čas běhu programu a popř ho zabít teda nevím. Já to udělal hrozně prasecky:
Po přijetí klienta jsem se forknul na 3 procesy. První proces si zjistil kolik je hodin a zapamatoval si to. Potom pollnul na pajpě. Druhý proces čekal na skončení třetího procesu a po wait napsal do pajpy nějaký znak. Třetí proces se execnul na daný program a argumenty.

Jinak řečeno - Třetí proces se execne, druhý na něj čeká a až se dočká pošle něco do pajpy, čímž probudí poll v prvním procesu (pokud už nebyl timeout). Strašně jednoduchý princip, ale je to napsané hrozně. Panu Kotalovi se to moc nelíbilo, ale jelikož mi to fungovalo a nebyly tam žádné chyby nebo neošetřené exitcodes ani memory leaks, zeptal se mě na pár otázek z teorie a dal mi dvojku. Btw tu teorii chtěl docela detailně.

Můj hnus (na dvojku s ucházející znalostí teorie stačilo): http://pastebin.com/PJW1xHH4
petrbel

Re: Zkouška 22.1.2013 - Kotal

Příspěvek od petrbel »

ještě abych nezapomněl, jako bonus pro rychlé jsme měli udělat handler na SIGINT, který správně zavře sockety a zabije všechny subprocesy.
Odpovědět

Zpět na „SWI015 Programování v Unixu“