From: Serdar KÖYLÜ (serdarkoylu@fisek.com.tr)
Date: Wed 03 Mar 2004 - 05:26:05 EST
Selamlar Cumleten..
> Bilgileriniz için önce çok teşekkürler,,,
>
> ben fork ile ilgili bir örnek (sws_webserver) bulup oradan yola çıkarak bişi ler yaptım ama şindiki sorunum
> fork ile çalışan süreçe bilgi aktaramıyorum
> kod şöyle;
> lcd_init ();
> if (!fork ())
Simdi fork() geri donen degerleri 3 farkli sekilde yorumlanir:
1. Eger deger -1 ise, fork is gormemistir.
2. Eger deger 0 ise, siz child process'iniz.
3. Eger deger baska bir seyse, siz ayni process olarak devam ediyorsunuz
Simdi genel bir fork anlatici kodu soyle yazabiliriz
pid_t pid;
int status;
pid = fork();
if (pid == -1) {
. printf("FORK olmadi, biraz daha RAM almak gerekiyor\n");
} else {
. if (pid == 0) { // Burasi child..
// Child kodunu buraya yazin.
. } else {
. // Main program kodunu buraya yazin.
. waitpid(pid, &status, 0); // Boyle yapmazsaniz
. // child olunce defunc olur..
. }
}
Oysa asagida da goruldugu gibi, sizin kodunuz sadece child kodu tarafina
gidiyor. Gerci boyle yaparakta ayni etkiye ulasirsiniz, ama hic mola
vermeden while(1) icinde donup durmak harbi saglam CPU yuku demektir.
Programinizin IDLE olacagi sureleri saglamalisiniz.
> {
> while (1)
> {
> lcd_update (); buraya lcd_update(line) gibi değiştirdima ama olmadı
> }
> }
> while (1)
> {
> fd = open_port ();
> bufptr = buffer;
> while ((nbytes =
> read (fd, bufptr,
> buffer + sizeof (buffer) - bufptr - 1)) > 0)
Simdi burada read()'in ne zaman geri donecegini bilebiliyormusunuz ?
Hayir, skb'ler filan derken tam bu noktada bloke olursunuz. Zaten bu tur
yurutmeyede blocking I/O denir. Bunun en iyi cozumu, non-blocking I/O ve
async signalleri kullanmaktir.
Benim bildigim open_port() diye bir fonksiyon yok. Sanirim bir library
vs. uygulamasi. Bu yuzden dogru yorumu yapmam zor. Ama gideceginiz yol
kabaca:
1. port'u acin, fd elde edin.
2. fd'nin sahibi benim deyin:
int fd;
int main(...) {
...
...
. fcntl(fd, F_SETOWN, getpid());
3. bir signal handler olusturun, soketten okusun:
void handler(int a) {
buffer_size = read(fd, buffer, size_of_buffer);
}
4. Signal handleri kurun:
struct sigaction saio; // Signal action
saio.sa_handler = handler;
saio.sa_flags = 0;
sigaction(SIGIO, &saio, 0);
5. ASYNC moda gecirin soketi:
fcntl(fd, F_SETFL, FASYNC);
Sonra siz isinize bakin, okunacak bir sey geldikce handler() otomatik
devreye girer, okur ve buffer'a koyar..
Gerci bu bu kadar basittir, ama bazi puf noktalari da vardir. Oncelikle
birisi bufferle ugrasirken digeri onu degistirir hale gelebilir ki
bilinen race condition mevzusudur. Bu tur sorunlarin en basit cozumude
circular buffer veya ayri ayri iki buffer kullanmakla olur. Ha, bu en
iyi cozum degildir, ama en kolayidir.
Yukarida, eksik fazla yazilmis, atlanmis bir seyler olabilir, ayakustu
yaziyorum ama temel prensipleri gostermeye yeter saniyorum..
Saygi ve sevgiler..
> {
> bufptr += nbytes;
> if (bufptr[-1] == '\n' || bufptr[-1] == '\r')
> close (fd);
> break;
> }
> barkod = strtok (buffer, "P");
> sprintf (line, "AA%s%5.5s\n", gettime (), barkod);
> printf ("%s", line);
> dosya = fopen ("barkod.db", "at");
> fprintf (dosya, line);
> fclose (dosya);
> sprintf (line, " Kroman Celik~Barkod :%5.5s", barkod);
> }