[ Predrag Damnjanovic @ 31.08.2002. 00:31 ] @
Preedator je cini mi se pisao prost primer clienta i servera, pa ako neko ima neka okaci ovde.
Treba mi za UNIX client.c i server.c, posto moraju da se koriste i neke dodatne WINAPI f-je da bi se socket inicijalizovao.
[ Dejan Lozanovic @ 31.08.2002. 11:09 ] @
Odmah dodje, sto bi rekli u nekoj seriji :)) pored obicnog klijenta i servera poslao sam ti primer kako izgleda TCP server unutar jednog procesa bez tredova :)), a pored toga sam ti dodao i ostale metode interprocesne komunikacije, preko redova poruka, a i mozes da vidis kako se radi sa deljenom memorijom :)) pod UNIX-ima :)

PS Zaboravio sam da kazem da je sve primere napisao Nebojsa Vasiljevic(asistent na matematickom fakultetu)
[ Predrag Damnjanovic @ 31.08.2002. 15:54 ] @
Hvala.
Kako ono ti rece, apetiti rastu :), resio sam da napravim web server :)
Mada, prvo cu da napravim f-ju koja se kaci na SMTP i salje mail, Weird napisao dobar clanak u kome objasnjava SMTP protokol.
[ Dragi Tata @ 31.08.2002. 19:14 ] @
Primeri koje je Dejan ostavio su dobri za upoznavanje sa osnovnim socket funkcijama. Međutim, za real-life servere metoda "jedan po jedan klijent" ne dolazi u obzir. Jedino stvarno dobro rešenje za takve aplikacije je thread pool - mada izgleda da se pod Linux-om i process pool podjednako dobro ponaša. U svakom slučaju, ako hoćeš time ozbiljno da se baviš, probaj negde da nađeš ovu knjigu:

http://www.kohala.com/start/unpv12e.html
[ Dragi Tata @ 31.08.2002. 19:16 ] @
I, naravno, umalo da zaboravim, pogledaj

http://www.codeproject.com/internet/#Beginners

Posebno su dobri članci Len Holgate-a. Kad njih "svariš", onda možeš ozbiljno da se baviš network programiranjem.
[ Dejan Lozanovic @ 31.08.2002. 20:29 ] @
Citat:
Dragi Tata:
U svakom slučaju, ako hoćeš time ozbiljno da se baviš, probaj negde da nađeš ovu knjigu:

http://www.kohala.com/start/unpv12e.html

Dobra je ta knjiga mada mislim da je ova ipak egzoticnija, po pitajnju tema koje obuhvata. U svakom slucaju rado bih obe imao na polici.

http://www.kohala.com/start/tcpipiv2.html
[ tOwk @ 01.09.2002. 04:18 ] @
Da ne planira ko da piše TCP/IP stek, ili neku potpunu socket biblioteku?

Ako planira, siguran sam da će mu poslednja pomenuta knjiga (TCP/IP Illustrated, Volume 2: The Implementation) pomoći, mada je tada nezaobilazna dokumentacija svaki RFC i IEEE STD koji definiše neki od osnovnih protokola.

Ako već voliš preciznu dokumentaciju, onda je ,,standard'' standard —
http://www.unix-systems.org/single_unix_specification/ — Single Unix Specification v3 (ili kada je izda IEEE ili ISO — ne znam tačno koji — postane POSIX, i najverovatnije UNIX2003).

Uostalom, osnovna referenca za upotrebu osnovnih Unix alata, programiranje pod Unix sistemima, i još mnogo toga je upravo SUS.

Nadam se da je od pomoći.
[ Predrag Damnjanovic @ 01.09.2002. 14:51 ] @
Tata, slazem se da metoda klijent-po-klijent nije prihvatljiva za ozbiljan servis, ali samo zato sto drugi klijenti moraju da cekaju dok server obradjuje zahtev jednog klijenta.
A sta mislis (pitanje vazi i za ostale) da se od onog primera (chatserv.c) napravi multi-thread server, nesto kao Apache?
Znaci pri startu kreira recimo 5 pod-procesa, koji cekaju da ih glavna nit 'zaposli'?
Tu bi znaci glavna nit samo cekala da se nova konekcija uspostavi, a zatim dalju komunikaciju prepustala nekom pod-procesu (koji je slobodan)?

Ne znam da li ste gledali chatserv.c, ali on koristi FD_SET.
Ja jos ne znam sta je ovo, pa ako neko zna, neka mi objasni.

Glavna rutina mu izgleda ovako:

Code:

  while(1) {

    clients_fds();

    FD_SET(sd,&rfds); /* za accept */

    do {
      sret=select(MAX_CLIENTS,&rfds,NULL,NULL,NULL);    // hvata dogadjaj
    } while(sret<0 && errno==EINTR);

    if(sret<0) {perror("select"); exit(1);}

    if(FD_ISSET(sd,&rfds)) nov_klijent(sd);        // nova konekcija

    for(i=0;i<MAX_CLIENTS;i++)
      if(FD_ISSET(i,&rfds) && clients[i].status!=0)
      {
    int l,j;
    l=read(i,buf,sizeof(buf));

    if(l==0) [..] fprintf(stderr,"Konekcija %d zatvorena\n",i);
    if (l>0) [..] stigla_poruka(i);
      }
  }


a promenljiva sd je:
Code:

int sd;
sd=socket(AF_INET,SOCK_STREAM,0);


Ono [..] sam ja snip-ovao kod koji je nebitan za analizu.

Ovde mi, kao sto rekoh, uopste nije jasna uloga FD_SET-a i FD-ISSET-a, kao i ona f-ja "select", koja hvata dogadjaje.
Sve ostalo je jasno kao dan.

BTW, ja bih thread ubacio onde gde se uspostavlja nova konekcija.
Ali, ne znam kako da izdvojim da novo-kreirani thread osluskuje samo njegovog klijenta... :(

I na kraju, kad bih ja uspeo to sto hocu, da li bi to bilo "prihvatljivo" za neki ozbiljan daemon (naravno pod uslovom da imam dobru organizaciju, tj. da jedan thread ne remeti druge thread-eve)?

Ako mozete pomognite, ja cu danas da probam da napravim od ovoga multi-thread server. :)
Ili ako neko vec ima gotov primer multi-thread servera, dobro bi dosao.
[ Dejan Lozanovic @ 01.09.2002. 15:32 ] @
pa vidi, glavna funkcija je select, a FD_ZERO, FD_SET su pomocne funkcije. naime slect funkcija ti kaze koji su fajl desktriptori spremni za citanje,pisanje, i onaj treci red specijalne namene. znaci recimo hoces da ti program istovemeno cita sa standarnog ulaza i da gleda da li je nesto doslo na sa socketa, onda lepo stavis 0 i socket deskriptor u isti kos(fd_set) i ubacis ih u select.

Sada se verovatno pitas a cemu sve to tako, pa recimo I/O sistemski pozivi mogu da blokiraju. pa ako das obicno prvo da citas sa tastarue pa sa socekta, blokiraces citanje sa socketa, i obrnuto. Slicna stvar je i sa write.

A za kraj pogledaj man select, i sve ce ti se samo kasti :))

Opet jeste da je bolja varijanta da se server organizuje preko threadova, tj lakse da se implementira, ali sa druge strane Ne bih ja tako rekao da je ovo u jednom procesu toliko lose. Jer zamislite se malo koliko hiljada puta procesor brzi, od ostalih uredjaja, pogotovo ulazno izlaznih kao sto su hard disk, mrezni uredjaji itd.. sto daje vremena programu da odradi sve. Tako da sve u svemu ne bih ja bas toliko crvsto verovao da je jedan procves bez thredova toliko losa stvar.
[ Predrag Damnjanovic @ 01.09.2002. 16:57 ] @
Evo nasao sam odlican server.c koji radi sa pthread-om :)
Radi super, cak se i kompajlira bez ijednog warninga (onaj tvoj se zali na pogresan tip pointera).
Hvala u svakom slucaju svima na dosadasnjoj pomoci.
[ Dragi Tata @ 01.09.2002. 19:38 ] @
Citat:
Dejan Lozanovic:
Tako da sve u svemu ne bih ja bas toliko crvsto verovao da je jedan procves bez thredova toliko losa stvar.


To je sasvim prihvatljivo pod uslovom

1. Da server odradi nešto kratko
2. Da je saobraćaj umeren.

Međutim, zamisli situaciju u kojoj server treba da pročita nešto iz baze (ili da zapiše u nju) ili da izvrši neki proračun ili bilo šta što traje. E sad, zamisli da stigne recimo 10 klijenata (10 je još uvek mala cifra-šta ako stigne 1000 klijenata?) "istovremeno". Server će da "zaglavi" rešavajući prvi zahtev, a ostali će da čekaju. Onda server rešava drugi zahtev, pa tako redom do desetog. Ovo je potpuno neprihvatljivo.

Jedan proces - jedan nit sa funkcijama kao što je select ili poll je radilo u vreme kad je internet bio "mali", i kada se u praksi retko dešavalo da imate više od jednog zahteva istovremeno. Danas se tako stvari ne rade. Čak je i "fork-ovanje" na svakog klijenta preskupo. Jedini ispravan način za pravljenje mrežnih server aplikacija je "thread pool", a kod nekih varijanti Unix-a može i "process pool" - znači kreiraš niti (procese) unapred i onda one čekaju spremne da obrade nove zahteve.
[ leka @ 02.09.2002. 15:44 ] @
Nemanja, necu da gresim dusu, u pravu si kad je fork u pitanju, ali ima tu jedna druga stvar - rad sa procesima je na UNIX-u i Linux-u mnoooog jednostavniji i MANJE ZAHTEVAN od rada sa procesima na Windows-u. Covek sebi bez problema moze da dozvoli da koristi fork() na Linux-u cak i da je server mnogo vise poseceniji nego sto ti kazes.
Naravno, generalno se slazem da je fork() kas su u pitanju serverske aplikacije losije resenje od niti, ali ne TOLIKO losije kako neki pricaju...

Hocu da kazem da malo preuvelicavamo stvari...

Ako se vec toliko govori o stednji resursa, onda mi recite zar MFC ne jede resurse ko lud, pa ga ljudi opet koriste...
[ Ivan Dimkovic @ 02.09.2002. 15:56 ] @
Tacno, MFC jeste zderac resursa - ali niko lud ne bi pisao web server core sa MFC-om :)) Tako da je poredjenje malo nepravedno.. :)
[ Dragi Tata @ 02.09.2002. 18:26 ] @
Citat:
leka:
Nemanja, necu da gresim dusu, u pravu si kad je fork u pitanju, ali ima tu jedna druga stvar - rad sa procesima je na UNIX-u i Linux-u mnoooog jednostavniji i MANJE ZAHTEVAN od rada sa procesima na Windows-u. Covek sebi bez problema moze da dozvoli da koristi fork() na Linux-u cak i da je server mnogo vise poseceniji nego sto ti kazes.


Leko, ako se sećaš linka koji si ti ostavio pre neki mesec (da ga ne tražim sada), neki čovek iz IBM-a je pokazao da Linux kreira procese i niti 30-50% brže nego Windows, a to je za server aplikacije i dalje presporo.

Uostalom, treba razdvojiti dve stvari. Ako fork-uješ ili praviš nit na svaki zahtev, to ne valja ni pod Linux-om ni pod Windows-om (slažem se da je "manje loše" pod Linux-om, ali je i dalje loše). Ako napraviš "pool" - iliti "rezervu" niti ili procesa koji će da čekaju na nove zahteve, onda je na Linux-u praktično svejedno da li si fork-ovao (Apache 1.3) ili startovao niti (Apache 2.0) - nema nikakve razlike u performansama. Međutim, skrenuo bih pažnju ovde na jednu drugu "sitnicu". Apache 2.0 pod Windows-om je brži nego Apache 2.0 (i 1.3) pod Linux-om posebno pri većim opterećenjima. Razlog za to je činjenica da Linux (i ostali Unix-i koliko znam) nemaju mehanizam kao što je IO Completion Ports koji omogućava maksimalno iskorišćavanje CPU resursa pri velikim opterećenjima. Apache 2.0 za Windows koristi IO Completion Ports, kao i funkciju AcceptEx i rezultati su fantastični: stigli su IIS po brzini.

Na Win2k:


Na Linux-u:



Evo celog teksta:
http://www.eweek.com/article2/0,3959,15300,00.asp


[ tOwk @ 03.09.2002. 03:06 ] @
Skrenuo bih pažnju na podatak sa pomenute stranice:

Citat:
In all tests the web servers were in their default configurations and were not tuned for performance.


Naime, čini mi se da Apache u default konfiguraciji dolazi sa podešavanjima namenjenim manjim serverima (tj. serverima sa manjim opterećenjem). Apache 2.0 čak kombinuje multi-process i multi-thread model. Tako, po pokretanju Apache servera se može podesiti koliko će zasebnih procesa pokrenuti na samom početku, i kako će se pokretati nove niti. Ovo veoma mnogo utiče na same performanse servera, a naročito pod značajnijim opterećenjem (ili to samo meni tako izgleda iz mog ugla; ja nemam nijedan ovako dobar članak da to potkrepim :)

Prema tome, i IIS i Apache se mogu sigurno dodatno ubrzati nekim ,,finim'' podešavanjima. Pitanje je samo koji se može ubrzati više, i kakav će onda odnos biti. Naravno, ne smemo ni zaboraviti da su testovi sigurno rađeni na svežim instalacijama W2K i RedHat Linux (nisam čuo hvalospeve o njegovoj uobičajenoj konfiguraciji).


Dalje, moliću nekog da mi objasni razliku između niti i samih procesa. Koliko ja znam, isti su principi, a jedino se radi o deljenoj/zajedničkoj ili zasebnoj memoriji. Naravno, češći je slučaj u operativnim sistemima da veći ,,overhead'' ima postupak pokretanja procesa, a ne niti, ali to nije implicirano njihovom arhitekturom, već odlukama u dizajnu samih schedulera i ostalih delova OS-a (kao što se izbacuje deo ,,administracije'' procesa pri radu sa nitima).


Na osnovu svega rečenog, i naročito citata iz datog teksta, ne vidim da je utvrđeno bilo kakvo objektivno merilo koji radi brže, već samo koji je bolje prilagođen enormnim opterećenjima (ne znam koje su jedinice korišćene za opterećenje, možda tr/sec, ali na 25--240 je Linux+Apache brži od Win32+Apache).

Kada izbacite sve moje pretpostavke, ne ostane ništa od poruke, ali nadam se da vam ne smeta, i da ćete shvatiti poentu cele poruke: na osnovu par besmislenih, amaterski urađenih sličica ja se ne bih usudio da iznesem bilo kakvo mišljenje o sposobnostima ,,poređenog'' softvera.

Toliko
[ Dragi Tata @ 03.09.2002. 06:24 ] @
Smisao mog posta nije bio da poredim Linux vs Windows niti IIS vs Apache i unapred upozoravam da neću dozvoliti da diskusija uzme taj tok.

Sve što želim da dokažem je da kod projektovanja server-side aplikacija ne treba dozvoliti kreiranje niti (ili nedajbože procesa) na svaki zahtev klijenta, već da niti (ili procese) treba kreirati kod samog startovanja servera tako da spremne čekaju nove zahteve, obrađuju ih i onda "spavaju" do sledećeg zahteva. Ovo nisam ja izmislio, već možete pročitati u svakoj boljoj knjizi o server-side programiranju.

Princip koji sam naveo važi za sve OS-ove, ali se tehnike izvođenja znatno razlikuju. Kod Windowsa (sa NT kernelom, naravno) i npr. VMS-a postoji kernel objekat koji se zove IO Completion Port koji se koristi za raspored poslova među nitima koje čekaju na nove zahteve klijenata i ovaj mehanizam je praktično obavezno koristiti za pravljenje istinski skalabilnih server-side aplikacija pod Windows-ima. Kod Linux-a, sa druge strane (ovo važi za relativno "taze" verzije) izgleda da se najbolje performanse postižu ako sve niti (ili procesi - kod Linuxa je to skoro svejedno) iz "rezervoara" zovu funkciju accept za isti socket. Kad stigne zahtev klijenta probudiće se samo jedna nit (proces) i obraditi zahtev. Međutim, ovo rešenje ne važi za sve Unixoide: kod nekih od njih bi se desilo da se probude sve niti (procesi) koji zovu accept i onda nastaje problem koji se popularno naziva thundering herd, a kod nekih verzija će aplikacija jednostavno da "pukne". Više detalja možete naći u knjizi koju sam gore pomenuo.
[ Dragi Tata @ 03.09.2002. 07:09 ] @
Interesantan članak o tome kako je thundering herd problem rešen pod Linux-om

http://www.citi.umich.edu/proj...calability/reports/accept.html


Pitanje: zna li neko (random, Bojan, Gojko,...) kako je (i da li je) ovo rešeno kod BSD-a?
[ Predrag Damnjanovic @ 03.09.2002. 13:51 ] @
Code:

    while (1)
    {
        // accept connections
        newsock = sockaccept(pfs_sock);
        if (newsock < 0)
        {
            perror("sockaccept");
            exit(1);
        }
        pthread_create(&tid, NULL, (void*) &pfs_thread, (void*) newsock);
    }


So, newsock dobije brojcanu (int) vrednost nove konekcije, recimo 6, i digne (ili probudi vec uspavani) thread.
Pa, kako moze da se desi da probudi sve thread-ove?
Malo mi ova ideja (da probudi sve) deluje uvrnuto...

P.S. Leko, strtok nije thread safe! Ali zato strtok_r jeste...
[ tOwk @ 03.09.2002. 16:09 ] @
Citat:
Dragi Tata:
Smisao mog posta nije bio da poredim Linux vs Windows niti IIS vs Apache i unapred upozoravam da neću dozvoliti da diskusija uzme taj tok.


Primorao si nas da učitamo dva grafikona koji navodno nešto ilustruju. Samo sam skrenuo pažnju na to da nam ovi grafikoni ništa ne znače, i da si to mogao potpuno da izostaviš (nisam ni ja izvodio bilo kakva poređenja, pa je, nadam se, jasno da ni ja ne želim da diskusija preraste u raspravu ,,koji je bolji'').

Ako vam je moj mini-esej predugačak, verujem da je ipak manji od pomenutih grafikona.

Citat:

Sve što želim da dokažem je da kod projektovanja server-side aplikacija ne treba dozvoliti kreiranje niti (ili nedajbože procesa) na svaki zahtev klijenta, već da niti (ili procese) treba kreirati kod samog startovanja servera tako da spremne čekaju nove zahteve, obrađuju ih i onda "spavaju" do sledećeg zahteva. Ovo nisam ja izmislio, već možete pročitati u svakoj boljoj knjizi o server-side programiranju.


To je sve što si i trebao da kažeš. Uzgred, to ima smisla, i nijednog trenutka se ne bih usudio da protivrečim tako nečemu. Čak, tu se opet uključuje priča o ,,overhead-u'' pri pokretanju niti/procesa ili nastavku rada istih.

Međutim, moguće je da u nekim slučajevima (zavisno od implementacije samog operativnog sistema) brzina bude ista u oba slučaja (ako se npr. koristi swap file, u koji je prebačena sama nit — potrebno je pregledati kernel strukture u kojima se sa niti mapiraju u memoriji, zatim CPU ili opet kernel pregleda pagetables, izazove izuzetak, kernel pregleda gde se nalazi swapfile, izvrši mapiranje po blokovima diska i konačno učita nit u memoriju; u direktnom učitavanju sa diska imamo samo poslednja dva koraka, kao i proces unosa u tabele samog jezgra i slično — naravno sve ovo je veoma pojednostavljeno, ali nadam se da razumete o čemu pišem).

I pored ovog drastičnog primera, rešenje sa ,,iščekujućim'' nitima/procesima je bolje zbog male učestanosti ovakvih okolnosti. Takođe, u svakom slučaju je vreme potrebno za ponovno pokretanje već učitane niti najviše jednako (tj. manje ili jednako) vremenu za učitavanje sa diska. Ovo je opet gruba procena, ali bi trebalo da bude razlog za upotrebu ovog mehanizma.



Citat:

[Nešto dobrog teksta isečeno]
Međutim, ovo rešenje ne važi za sve Unixoide: kod nekih od njih bi se desilo da se probude sve niti (procesi) koji zovu accept i onda nastaje problem koji se popularno naziva thundering herd, a kod nekih verzija će aplikacija jednostavno da "pukne". Više detalja možete naći u knjizi koju sam gore pomenuo.


Predlog literature izgleda dobro, čim budem imao vremena, pokušaću da je potražim, pošto u svakom slučaju izgleda kao zanimljiv dodatak kućnoj biblioteci (kako sumnjam da je ,,za dž'', ako ko ima verziju u PDF/PS varijanti, voleo bih da je imam; može i papirna na prodaju, ali da ne košta $100). Ako ne, i standard će poslužiti.

Toliko
[ leka @ 03.09.2002. 16:45 ] @
Citat:

P.S. Leko, strtok nije thread safe! Ali zato strtok_r jeste...


Da li je trebalo da kada kazem da su sve standardne C funkcije thread safe kazem da postoje i adekvatne *_r() funkcije za one koje nisu? Daaj bre... Mojne zezas sad. Ko zna za POSIX, zna i za tih par desetina funkcija...
Ako moramo da se bas hvatamo za reci onda okej - mozemo da otkopamo ratne sekire i nek bitka otpocne!
[ Dragi Tata @ 03.09.2002. 17:18 ] @
Citat:
Predrag Damnjanovic:
Code:

    while (1)
    {
        // accept connections
        newsock = sockaccept(pfs_sock);
        if (newsock < 0)
        {
            perror("sockaccept");
            exit(1);
        }
        pthread_create(&tid, NULL, (void*) &pfs_thread, (void*) newsock);
    }




Peco, ja se polomih da objasnim da ovaj pristup ne valja. Da budem precizniji, može lepo da radi sa malim brojem zahteva, ali kod većeg saobraćaja dolazi do naglog pada performansi.

Ono što ti predlažem (Linux varijanta) je:
1. Kreiraš socket koji "sluša" port 80
2. Kreiraš jedno 5 niti (ili forkuješ 5 procesa, kako ti je lakše) i svaki od njih zove accept () na isti onaj socket koji si kreirao pod 1). Dakle, pthread_create zoveš samo na početku programa. Svaka od ovih niti (procesa) obrađuje po jedan korisnikov zahtev, a onda opet zove accept() i to je baci u "usnulo stanje" dok ne stigne sledeći klijent.

[ Predrag Damnjanovic @ 03.09.2002. 17:55 ] @
Peco legendo, demantovanje je ovde sasvim DOBRODOSLO :) Ja volim ako mi neko ukaze na gresku. Ali takve sitne stvari... :)

Citat:

P.S. Leko, nisam hteo nista lose, izvini ako si pomislio da sam hteo da te demantujem.

[ Predrag Damnjanovic @ 03.09.2002. 20:18 ] @
Citat:
Dragi Tata:
Citat:
Predrag Damnjanovic:
Code:

    while (1)
    {
        // accept connections
        newsock = sockaccept(pfs_sock);
        if (newsock < 0)
        {
            perror("sockaccept");
            exit(1);
        }
        pthread_create(&tid, NULL, (void*) &pfs_thread, (void*) newsock);
    }




Peco, ja se polomih da objasnim da ovaj pristup ne valja. Da budem precizniji, može lepo da radi sa malim brojem zahteva, ali kod većeg saobraćaja dolazi do naglog pada performansi.


Tata, naglasio sam 'i digne (ili probudi vec uspavani) thread".
Nebitno je za ovu diskusiju da li otvaram thread pri svakoj konekciji ili budim uspavani thread.
Zamisli da imam 5 threada koji spavaju, i da ih pri novoj konekciji samo budim - i prepustam im komunikaciju sa novim klijentom.
Kako onda f-ja accept moze da probudi sve procese?
[ Dragi Tata @ 03.09.2002. 20:43 ] @
OK, Peco, nisam te razumeo najbolje. Ako radiš tako kako si ti napisao (glavna nit čeka na accept i po potrebi "budi" neku od niti koje spavaju), onda zaista nećeš imati problema sa thundering herd-om. Međutim, u praksi se ne radi tako (opet zbog performansi), već svaka od tih "uspavanih" niti direktno zove accept (odnosno, često select, pa tek posle accept, ali to je nebitno za ovu priču) za isti socket. Kada stigne klijent, kod nekih Unixoida (među njima je i Linux 2.2) će se desiti da se sve te niti "probude" u isto vreme, a ne samo jedna.

Pogledaj malo http://httpd.apache.org/docs/misc/perf-tuning.html#compiletime

ili još bolje fajl http_main.c iz Apache servera.
[ Dejan Lozanovic @ 03.09.2002. 20:51 ] @
Citat:
Dragi Tata:
Međutim, ovo rešenje ne važi za sve Unixoide: kod nekih od njih bi se desilo da se probude sve niti (procesi) koji zovu accept i onda nastaje problem koji se popularno naziva thundering herd, a kod nekih verzija će aplikacija jednostavno da "pukne". Više detalja možete naći u knjizi koju sam gore pomenuo.


Pa nista, specijalno u principu radi se o jednoj kriticnoj sekciji(CS).

CS(nemoj neko da mi je pomislio da je rec o counter stike-u :) ) je deo programa u kojem sme da bude samo jedan proces, ukoliko se u tom delu programa nadju dva ili vise procesa kola krecu nizbrdo, ovim problemom bavili su se ljudi pocetkom 60 tih godina proslog veka. Unutar Sys V interprocesne komunikacije postoje semafore, koje regulisu pristup kriticnim sekcijama(man semop). S tim sto su semafore malo uopstenje kriticne sekcije jer dozvoljavaju da ogranicite broj procesa koji sme da udje istovremeno u kriticnu sekciju.

za detalje oko semafora pogledajte (man semop). Medjutim ukoliko vas UNIX ne podrzava semafore kao sistemski poziv uvek mozete umesto semafore da ekskluzivno kreitrate datoteke i na taj nacin kontorlisete ko moze da udje a ko mora da saceka. Uz primere koje sam na pocetku poslao pogledajte program shmchat.c jer se u tom primeru koriste semafore. (gde P; u programu oznacava ulazak u kriticnu sekciju a V; izlazak iz kriticne sekcije)

e pa da se vratimo na nas accpet, posto on na neki nacin moze da se smatra kriticnom sekcijom svesto bi trebalo uraditi jeste
P
accept
V

i stvar je resena, ukoliko neko pokusa da udje u kriticnu sekciju dok ona nije slobodna, taj proces se "zaspati" i probuiti se kada bude bio moguc ulazak u kriticnu sekciju.
[ leka @ 04.09.2002. 12:35 ] @
Ima jedna stvar u prici o Apache web serveru koja nikome izgleda nije pala na pamet - Apache nije najbrzi web server ljudi. Postoje mnogo brzi od njega. Na stranu to sto je najpopularniji, ali najbrzi definitivno nije.

Drugo, na Apache 2.0.x su radili mnogo vise na optimizaciji za Windows platformu nego na optimizaciji za ostale sisteme, izgleda da im je namera da totalno dokrajce sve ostale web servere za Windows , specijalno IIS koji je smesan u poredjenju sa Apache web serverom.
[ Predrag Damnjanovic @ 04.09.2002. 13:09 ] @
Citat:
Dragi Tata:
već svaka od tih "uspavanih" niti direktno zove accept (odnosno, često select, pa tek posle accept, ali to je nebitno za ovu priču) za isti socket. Kada stigne klijent, kod nekih Unixoida (među njima je i Linux 2.2) će se desiti da se sve te niti "probude" u isto vreme, a ne samo jedna.

E sad je jasno Tata
Zahvaljujem na odgovoru.
Zahvaljujem i NULL-u za objasnjenje kako organizovati semafore u multi-thread aplikacijama.
[ Dragi Tata @ 04.09.2002. 17:23 ] @
Citat:
Dejan Lozanovic:

e pa da se vratimo na nas accpet, posto on na neki nacin moze da se smatra kriticnom sekcijom svesto bi trebalo uraditi jeste
P
accept
V


Tako je. Upravo to rešenje koristi Apache kod sistema koji "pate" od thundering herd problema. Međutim, ako pogledaš onaj link koji sam ostavio na tekst o thundering herd-u pod Linux-om, videćeš kolika je razlika u performansama kad se radi na način koji si opisao u poređenju sa rešenjem ugrađenim u kernel koje omogućava da se accept zove neserijalizovano.