Gaminu tokį serverį. Viskas sukasi ant Linux, dirbu su C++ ir POSIX gijomis. Serveris gauna užklausas iš kliento, jas atitinkamai įvykdo ir grąžina (čia reik nosinės? ne?) rezultatus klientui. Viskas turi vykti maksimaliu greičiu. Užklausos gali eiti iš 100 klientų vienu metu, tad siekiant didžiausios spartos be gijų (threadų, jei kam nors taip labiau patinka) neapsieisim. Dabar visas serverio darbas vyksta maždaug taip: gaunama užklausa iš kliento, listenerio gija nuskaito iš socketo atėjusią užduotį ir įrašo į FIFO eilę. Tuo pat metu sukasi n gijų, kurios yra atsakingos už darbų atlikimus. Šių gijų kodas atrodo taip:
void * worker(void * parm)
{
Step step;
bool gotData = false;
while (serverOn)
{
pthread_mutex_lock(&mutex);
if (!eile.empty())
{
step = eile.pop();
gotData = true;
}
pthread_mutex_unlock(&mutex);
if (gotData)
{
std::string result = readData(*step.sock, step.number);
setResult(*(step.sock), result);
delete step.sock;
gotData = false;
}
sleep(1); //Atkreipkit dėmesį čia.
}
}
Kaip matot, gija dirba nuolat, kol yra įjungtas serveris. Užrakinamas mutexas, jei yra darbų, nusiskaitomas darbas, mutexas atrakinamas ir vykdomi reikalingi veiksmai. Viskas paprasta ir aišku, tik man ramybės neduoda tas sleep(1);. Jį įdėjau tam, kad jei kodas būna be jo, labai ėdami CPU resursai, nes ciklas nuolat sukasi nieko naudingo neveikdamas. O su sleep(1) yra įvedamas kažkoks taktas. Žinau, kad tai nėra geriausias pasirinkimas, nes kažkurį laiko momentą gijos nieko neveiks, nors ir bus darbų. Veltui švaistomas laikas. Kadangi su tokiu darbu susidūriau pirmą kartą, tai tiksliai ir nežinau kaip viskas yra daroma, kad sprendimas būtų optimaliausias. Gal kas turit idėjų kaip sinchronizavimą padaryt veiksmingesniu?
em tam yra condition variablai, viena threada uzslypini kad laukto kol condtinion variable\\\’as bus reikiamoj bulkej ir kai nusiunti duomenu transliuoji pranseisma, uzblokuotas threadas atsigauna, padaro ka reik ir vel sau block\\\’uojamas buna ir tt
labai reikia -galeciau koda parodyti veikianti :)
Tai dabar taip ir padariau. Pakūriau vieną giją, kuri nuolat suktusi ir tikrintų ar yra darbų. Jei yra, tai su pthread_cond_signal siunčiu signalą kitiem. O tuo tarpu kiti su pthread_cond_wait laukia to signalo ir jį gavę atlieka savo darbus.
Šiaip jei nesunku, mestelk tą kodą, įdomu būtų pasižiūrėt :-)
na nevisai taip :) gaunasi kad ta gija kuri tikrina ar yra darbo irgi kabo ant ciklo yr svaisto cpu. paprastai darbo atsiranda tik pliupsniais (neaisku ka daro ta tavo programa).
o koda jau daviau
Ačiū už kodą, jau mačiau, tik dar nespėjau išsinagrinėti. Vakar buvau susikonstravęs, kad apie darbą būtų pranešta, kai ateina užklausa. Tačiau ar dėl mano klaidų, ar dėl ko kito, spartos testo rezultatai nuvylė. Tad galų gale pakeičiau sleep į usleep ir nurodžiau kiek mažesnį laiko intervalą nei viena sekundė. Taip procesoriaus resursai nėra labai valgomi, o ir atsakymų sparta vos ne ideali.
Beje, taip veikia dar greičiau nei su nuolat besisukančia gija :-) Padariau išvadą, kad dėl to, jog CPU nėra taip apkraunamas ir gali apdoroti duomenis.