From: Linux-Sevenler (velia@linux-sevenler.org)
Date: Wed 03 Mar 2004 - 06:30:45 EST
On Wed, 03 Mar 2004 12:26:05 +0200
Serdar KÖYLÜ <serdarkoylu@fisek.com.tr> wrote:
> 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.
>
Bilginin fazlası olmaz ne öğrensek kardır biraz kuracalamayla sorunu hallettim ama
işlem ci yükü falan fazla düşünmedim
aşağı daki kodun eksileri neler olabilir
main (int argc, char *argv[])
{
pthread_t lcd_update;
pthread_t barkod_update;
pthread_attr_t pthread_custom_attr;
lcd_init ();
pthread_attr_init (&pthread_custom_attr);
pthread_create (&lcd_update, &pthread_custom_attr, lcd_update_func,
NULL);
pthread_create (&barkod_update, &pthread_custom_attr,
barkod_lcd_update_func, NULL);
while (1)
{
pthread_join (lcd_update, NULL);
pthread_join (barkod_update, NULL);
}
return 0;
}
> 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);
> > }
>
>
>
>