Tam Sürümünü Görmek İçin : signal.h
quasimodo
30/03/2007, 15:31
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
void signal_handler( int );
int main()
{
int i, x;
signal( SIGINT, signal_handler ); /* Bu satir */
srand( clock() );
for ( i = 1; i <= 100; i++ ) {
x = 1 + rand() % 50;
if ( x == 25 )
raise( SIGINT );
printf( "%4d", i );
if ( i % 10 == 0 )
printf( "\n" );
}
return 0;
}
void signal_handler( int signalValue )
{
int response;
printf( "%s%d%s\n%s",
"\nInterrupt signal ( ", signalValue, " ) received.",
"Do you wish to continue ( 1 = yes or 2 = no )? " );
scanf( "%d", &response );
while ( response != 1 && response != 2 ) {
printf( "( 1 = yes or 2 = no )? " );
scanf( "%d", &response );
}
if ( response == 1 )
signal( SIGINT, signal_handler );
else
exit( EXIT_SUCCESS );
}
Buradaki signal() ve raise() fonksiyonlarinin gorevi ney?
Program calismaya basladiktan sonra bu satira geldiginde
ne yapiyor.
acehreli
04/04/2007, 21:41
Programlar birbirleriyle isletim sisteminin sagladigi isaretlerle (signal) anlasabilirler. Bir program bir isaret aldiginda, o anda yapmakta oldugu is durdurulur ve program o isaret geldiginde hangi ozel seyi yapmak istiyorsa o yapilir.
En cok kullanilan isaret herhalde SIGINT'tir. Biz disaridan Ctrl-C'ye bastigimizda programlara SIGINT isareti gonderilir.
signal: Bir programin "ben bu isaret geldiginde su islevin cagrilmasini istiyroum" demesidir.
raise: Bir programin "ben kendi kendime su isareti gonderiyorum" demesidir.
Senin ornegindeki
signal(SIGINT, signal_handler);
cagrisi, SIGINT isareti geldiginde (ornegin Ctrl-C'ye basildiginda) signal_handler adli islevin cagrilmasini saglar.
raise(SIGINT);
ise sanki disaridan birisi programi sonlandirmak istemis gibi, ama kendi kendisine, SIGINT isaretini gonderir.
Isaretlerle ilgili cok onemli ama fazla da bilinmeyen bir ayrinti var: Isaret geldiginde calistirilan o ozel islevin calismasi sirasinda yine bir isaret gelirse ne olur?
Cok kotu seyler olabilir. Ornegin o islevin icinden bazi kutuphane islevlerini cagiramayiz. Onun icin, isaretle ilgili olan o ozel islevde, guvenli olarak yapilabilecek tek sey, o isaretin alinmis oldugunu bir kenara not etmektir. Ondan sonra, programin ana dOngUsu sirasinda boyle bir isaret alinip alinmadigina bakilir ve asil is o ana dOngU sirasinda yapilir.
Ornegin printf'in o ozel islevden cagrilmasi yanlistir. Onun icin senin ornegin aslinda hatali. (Bir "signal handler" icerisinden hangi islevlerin cagrilabildiklerini gosteren sayfalar gormustum ama simdi bulamiyorum. :( )
Bu isin guzel yollarindan birisi sigset_t tUrUnu kullanan sigaddset ve arkadaslarini kullanmaktir. Onlar da sonucta su yonteme benzer sekilde calisirlar:
int g_SIGINT_alindi = 0;
int main()
{
// Islevi belirliyoruz
signal(SIGINT, ozel_islev);
/* ... */
// Programin ana dOngUsU
while(/* ... */)
{
if (g_SIGINT_alindi)
{
// Ctrl-C'ye basilmis; temizlik yapip cikalim...
// Gerekirse printf burada yapilabilir
}
/* ... */
}
/* ... */
}
void ozel_islev(int isaret_degeri)
{
// Burada hic kutuphane islevi cagirmiyoruz;
// yalnizca bu isareti aldigimizi not ediyoruz.
if (isaret_degeri == SIGINT)
{
g_SIGINT_alindi = 1;
}
/* ... */
}
Ali
quasimodo
05/04/2007, 21:34
if ( response == 1 )
signal( SIGINT, signal_handler );
else
exit( EXIT_SUCCESS );
o ozel islevin icinde yazilmis bu kodda eger yanit 1 olursa ne oluyor.
yani ozel islevin icinden tekrar cagirilan
signal(SIGINT, signal_hangdel)
islevinin gorevi nedir...?
acehreli
05/04/2007, 22:08
Bir yerde gozume carptigina gore, bazi isletim sistemlerinde o isleve bir kere girmek, o islevle SIGINT'in iliskisini unutturuyormus. Onun icin her giriste tekrar signal'i cagirmak gerekiyormus. Bazi ortamlarda oyleymis; tasinabilir olmak icin gerekliymis...
Ben daha karsilasmamistim, senin sorunu yanitlarken ogrendim.
Ali
quasimodo
05/04/2007, 22:17
iliskilendirip, yonetimi tekrar main() e mi veriyor ...
isleve girdikten sonra
yanit 1 dersek cikti
60
61 62 63 64 65 ......69
71 72 ... 79
diye devam ediyor...?
acehreli
05/04/2007, 23:24
Evet, isaret islevinden cikilinca isaretin geldigi andaki yere donuluyor. Ornegin hangi noktada Ctrl-C'ye basilmissa, program o noktadan devam ediyor.
Ali
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.