Pazar, Mayıs 21, 2006

Client/Server2

Iyisin, hossun da sistemde bir kere calistiktan sonra neden calismiyorsun hic anlamadim!

You are supposed to create 3 periodic tasks (using thread or fork mechanism, it’s up to you).
The period of these tasks are 1, 5 and 10 seconds. The job of the first task is to write “I am task
1” on the screen, for the second task “I am task 2” and so on. Since these tasks are periodic, for
example, the first task will repeatedly say “I am task 1” each second, similarly the other tasks
will periodically run and print their messages on the screen.


#include "stdio.h"
#include"signal.h"

void handler1(int sig)
{
printf("I am task1");
signal(sig, handler1);
}

void handler2(int sig)
{
printf("I am task2");
signal(sig, handler2);
}

void handler3(int sig)
{
printf("I am task3");
signal(sig, handler3);
}

int processFork(void *sighandler){

int pid;

if((pid = fork())== -1){
printf("not forked!");
exit(-1);
}else if(pid == 0){
printf("forked!\n");
signal(SIGUSR1, sighandler);
printf("signalled!\n");
while(1)
{
sigpause(SIGUSR1);
printf("duut\n");
}
exit(0);
}

return pid;

}

int main(void)
{
int seconds;
int process1, process2, process3;

process1 = processFork(handler1);
process2 = processFork(handler2);
process3 = processFork(handler3);

printf("process 1 : %d\n", process1);
printf("process 2 : %d\n", process2);
printf("process 3 : %d\n", process3);
for(seconds = 0; seconds < 100; seconds++){
if(seconds % 1 == 0){
kill(process1, SIGUSR1);
}
if(seconds % 5 == 0){
kill(process2, SIGUSR1);
}
if(seconds % 10 == 0){
kill(process3, SIGUSR1);
}
sleep(1);
}

kill(process1, SIGKILL);
kill(process2, SIGKILL);
kill(process3, SIGKILL);

return 0;
}

14 yorum:

Bulent Murtezaoglu dedi ki...

Problem tarif edilenden ibaretse asagida kabaca vermeye calistigim gibi bir cozum niye yeterli degil?


//include vs.

void forkit (int taskno, int period)
{
switch (fork()) {
case -1 :
printf("not forked! tasnkno=%d\n", taskno);
exit(-1);
case 0 :
for(;;){
printf("I am task %d \n", taskno);
fflush(NULL);
sleep(period);}
}}

int main() {
forkit(1,1);
forkit(2,5);
forkit(3,10);}

Adsız dedi ki...

http://www.catb.org/%7Eesr/faqs/smart-questions.html#homework

sick princess dedi ki...
Bu yorum bir blog yöneticisi tarafından silindi.
sick princess dedi ki...

for( ; ; ){
// do some job
printf(“I am task2”);
// end of your job
sleep(5);
}
Therefore, you need to periodically activate the tasks with a higher time precision from a parent
process. For example, if you are using the fork mechanism, you can handle this by sending
SIGINT signals to the child processes.
To check whether your timing is precise, you can simply count the messages. For example, by
the 100th second, you will have seen 100 messages from task1, 20 messages from task2 and
10 messages from task3. However, if you used the above wrong code, you would see less than
100 messages from task1.
­­­­­
problemin devami, saygilar!

Bulent Murtezaoglu dedi ki...

Hmm, mesele sleep'ler cagrilincaya kadar zamanin kaymasi ise o zaman ana surecteki sleep() de olmaz, ben olsam interval-timer ile yapardim herhalde (setitimer). Tabii ayni sekilde interval-timeri cocuk sureclerde kullanmak da kabil. Hoca galiba timer mekanizmasini degil de odevin isminden anlasildigi gibi haberlesmeyi gostermek istiyor, onun icin bu ikinci gozlem sorunun ruhuna aykiri.

Kodda ne hata var bilmiyorum (goremedim, calistirmadim), verdigim ornek kodun gosterecegini umid ettigim sey fork'tan sonra adress spaceler ayrildigi icin uc ayri handler ve mesaja luzum olmadigiydi.

sick princess dedi ki...

Anladim, her processin kendi adres space i olmasi vs mevzuusu! Sinyallerle alakali bir mevzuu olmali, bir kere calistiktan sonra tekrar calismiyordu ama simdiki sinyallerle duzgun isliyor! Aslinda sleep yerine wait kullaniyorum ama burda boyle kaldi! Interval timer ne bilmiyorum arastirmam lazim, acikcasi ne farki olabilecegini de kestiremedim!

Ne sorunun ruhuna aykiri onu da anlamadim:S..
Ilginiz icin cok tesekkur ederim, cok sansliyim ki bildigini paylasmaktan mutluluk duyan insanlara rastliyorum hep.

//wait fonksiyonu
void wait(int seconds){

clock_t endwait;
endwait = clock() + seconds * CLK_TCK;
while(clock()< endwait){}
}
//sleep yerine wait(1);
//bir avantaji var mi bilmiyorum hic!

Bulent Murtezaoglu dedi ki...

Aman sleep yerine o wait'i kullanmayin. Sleep kendisini cagiran sureci uyutuyor, sizin o wait devamli calistiriyor. (Ayrica wait diye bir kutuphane fonksyonu varken kendi waitinizin olmasi kodu okumayi zor hale getirir).

Sleep/interval timer isi soyle. Odevde verilen ornekte oldugu gibi:

for(;;){
birsey();
sleep(T)}

kodu T saniyede bir degil, T saniye + bisey()'in surdugu zaman + dongunun aldigi zamanda calisiyor. Interval-timer'i soyle bir soyutlama olarak dusunebilirsiniz:

T kadar zaman gecince:
-- hemen yeniden T kadar zamana saat kur
-- birsey() yap

gordugunuz gibi bu sefer (birsey'in T'den az zaman aldigini farzedersek birsey'in surdugu zamandan bagimsiz olarak T zamanda bir calsiyor kod, kayma olmuyor.

Ruha aykirilik suradan cikiyor: interval-timer tipi bir cozum aslinda cekirdekle kullanici surecleri arasinda sizin ana surec ve cocuk surecler arasinda olan iliskiyi kurmaya yariyor. Hal bu olunca cocuklarda interval timer kullanmak da zaman kaymasina engel olsa dahi, odevin amaci oldugunu tahmin ettigim ana surece zaman hesabini tutturup cocuklari uyandirma duzenine gerek kalmiyor (cekirdek ana surec oluyor).

Aslinda bloglar bu sorular icin dogru bir yer degil. Trafik nispeten az oldugu icin sansa gorenlerden vakti olan olursa cevap veriyor. Fazlamesai.net gibi yerler, veya Ingilizce bildiginize gore usenet guruplari cok daha faydali olabilir.

sick princess dedi ki...

Sanirim kayma dedikleriniz instruction'larin islenme zamani, dediginizi deneyecegim.

burasi benim calismalarimi koydugum bir blog, hos fazlamesai ya da usenet gruplarina girip sorma gibi bir aliskanligim yok.

Hazir foksiyon yerine kendi yazma nedenin, icinde nelerin nasil olabilecegini gorup ogrenmek icin. Kodlarin okunarak degil impelemente edilerek ogrenilcegini, kavranilcagini dusunuyorum, tabi bu sadece benim fikrim. Tekrardan tsk ederim.

Processler 1, 5, 10 saniye vurusunda bir calistigina gore wait ne gibi bir problem yaratiyor anlayamadim..

Bulent Murtezaoglu dedi ki...

Ozellikle usenet'i tavsiye ederim. Ben araba tamir etmeyi dahi oradan ogrendim. Kotu bir aliskanlik degil. Bizim lisp gurubundan Erhan Kesken cok memnun kaldi usenetle tanismaktan mesela.

Fonksyonlari kendinizin yazmaniz elbette faydali. Benim kastim, kendinizin yazmanizin zararli oldugunu soylemek degil, islevsel olarak esdeger fonksyon yazmaniz ve isimlendirmede standart sayilacak kutuphaneleri dikkate almanizdi.

O wait devamli calisiyor, 1,5,10 saniyede degil. Yani sizin wait cagrildiginda sureci uyutmak yerine verilen sure kadar donup duruyor. Sleep'in yaptigi cekirdege 'beni su kadar sure _calistirma_' demek efektif olarak, dongulu wait ise devamli cekirdege 'saat kac' diye soruyor. Bunlarin altinda yatan mekanizmalar, bir surec nasil uyutulur filan dersinizin konusu mu bilmiyorum ama herhalde isletim sistemi dersinde bunlar gosterilir.

sick princess dedi ki...

Isletim sistemleri dersini aldim, ikisini de biliyorum. Zaman acisindan neden daha efektif oldugunu hala anlamadim.

Bilmedigim bir sey sleep islerken sistem kaynaklarinin nasil kullanildigi, o yuzden waitten daha iyi olan yanini hala anlayabilmis degilim. Ikisi de 1 parametre alan fonksiyon olduguna gore ne degisiyor?

Bulent Murtezaoglu dedi ki...

Tamam o zaman soyle dusunebilirsiniz. Sleep cagrildiginda uyanincaya kadar o surec runnable olmuyor, schedule edilmiyor, kaynak kullanmiyor. Sizin verdiginiz wait fonksyonuna bakarsak cagiran surec beklerken

while(clock()< endwait){}

yapiyor. Yani runnable, ve devamli clock()'u cagirip karsilastirma yaparak kaynak harciyor. Daha acik oldu mu?

sick princess dedi ki...

Bakin cidden wait in ne yaptigini biliyorum ama anlamadigim ya da bilmedigim sleep in nasil calistigi, sonucta sleep() cagiran fonksiyonu suspend konuma geciriyor ama 1sn gecip gecmedigini onunda kontrol etmesi gerekmiyor mu? ayrica runnable durumda kalmasi bir saniye gectikten sonra, programa daha hizli ulasilmasini saglamaz mi?

Yani sleep() sistem kaynaklarinin kullanimindan efficency saglarken wait() zaman acisindan saglar neden diyemiyoruz?

Bunlar cok ufak zamanlar olsa da mantigini anlamaya calsiyorum!

Bulent Murtezaoglu dedi ki...

Sleep'in cagiran surecin saate bakmasi gerekmiyor, onun icin uyuyabiliyor. Usendim, usenet arsivini aradim, sleep'i nasil yazariz diye kise bir ornek
buldum:

void nop(int unused) { }

int sleep(int secs) {
void (*old)(int);
old = signal(SIGALRM, nop);
alarm(secs);
pause();
signal(SIGALRM, old);

}

Bakin orada pause, alarm sinyali gelinceye kadar sureci durduruyor. Burada soz konusu olan ufak zamanlar degil, tamamen farkli yaklasimlar.

O sekilde yazilmis bir wait zaman acisindan nasil radimanli olur anlamadim. Bunlari denemek mumkun herhalde ama bence degecek birsey degil.

Ileride birisi bu sayfadan birseyler kapmak icin buraya gelirse kafasi karismasin diye hakiki wait 'ten bahsetmedigimizi de not duseyim dedim.

sick princess dedi ki...

Tamam tesekkur ederim!