[linux-programlama] Re: Aynı anda iki iºlem kontrol etmek

---------

From: Serdar KÖYLÜ (serdarkoylu@fisek.com.tr)
Date: Wed 03 Mar 2004 - 05:26:05 EST

  • Next message: Linux-Sevenler: "[linux-programlama] Re: Aynı anda iki iºlem kontrol etmek"

    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);
    > }


  • Next message: Linux-Sevenler: "[linux-programlama] Re: Aynı anda iki iºlem kontrol etmek"

    ---------

    Bu arsiv hypermail 2.1.6 tarafindan uretilmistir.