[ NikolaVeber @ 09.12.2003. 12:28 ] @
Pozdrav !

Da li bi mi neko ukratko objasnio sta su to niti, kako rade, za sta sluze....
Par recenica.

Hvala
[ Humanoid @ 10.12.2003. 21:37 ] @
Recimo da imas program koji u jednom trenutku treba nacrtati neku sliku i odsvirati neku melodiju(istodobno).To bi u klasicnom pristupu pomocu procedura i funkcija bilo nemoguce(valjda) zato sto bi se uvijek moralo pricekati da se izvrsi ono prvo(recimo crtanje slike),a onda drugo(melodija).Zato trebas upotrijebiti niti(Threads) ako zelis simultanost izvodjenja.Dakle,niti su dijelovi programa koji se izvode neovisno o izvodjenju glavnog potprograma(ili ostalih u programu).Naravno,trose se vise procesorski resursi,ali dobivas istovremenost.Windowsi imaju niti ugradjene u sebe,a mogu se koristiti u svim novijim razvojnim sustavima(pa cak i u Free Pascalu).Eto,nadam se da sam u svemu ovom rekao nesto pametno.
[ stalker @ 10.12.2003. 23:22 ] @
Evo kako sam ih ja naucio npr. Trebalo mi je u jednom programcicu ucitati neki veliki fajl, ali i prikazati progress bar. Ukoliko bi ucitavao fajl, progress bar se jednostavno nije refresh-ovao, pa sam iskoristio "glavni program" za crtanje, a napravio nit za ucitavanje fajla... Valjda je jos malo jasnije:(

BTW, ovo je bilo pravljeno u C-u. Istovetni program u VB-u je sve lepo radio bez niti!!! Pretpostavljam da se glupi VB za sve sam pobrine?
[ stalker @ 11.12.2003. 10:43 ] @
Ma nije bitno za ovu temu, samo sam stari program iz VB-a prebacivao u C. Ajmo malo o nitima...
[ alex @ 11.12.2003. 11:26 ] @
Threads FAQ:
http://www.serpentine.com/~bos/threads-faq/

Citat:

3. What are threads?
A thread is an encapsulation of the flow of control in a program. Most people are used to writing single-threaded programs - that is, programs that only execute one path through their code "at a time". Multithreaded programs may have several threads running through different code paths "simultaneously".
Why are some phrases above in quotes? In a typical process in which multiple threads exist, zero or more threads may actually be running at any one time. This depends on the number of CPUs the computer on which the process is running, and also on how the threads system is implemented. A machine with n CPUs can, intuitively enough, run no more than n threads in parallel, but it may give the appearance of running many more than n "simultaneously", by sharing the CPUs among threads.

3.1. Why are threads interesting?
A context switch between two threads in a single process is considerably cheaper than a context switch between two processes. In addition, the fact that all data except for stack and registers are shared between threads makes them a natural vehicle for expressing tasks that can be broken down into subtasks that can be run cooperatively.
[ leka @ 11.12.2003. 11:58 ] @
Da bi razumeo pojam "nit" moras razumeti dobro i pojam "proces". Zasto? - Nit je zapravo "laganiji" proces. Ukoliko znas osnovne stvari o procesima, onda znas da proces kao deo APLIKACIJE:
1) zna sve o resursima APLIKACIJE
2) PID, PID od grupe kojoj pripada, UID, GID (APLIKACIJE)
3) zna sve environment varijable (APLIKACIJE)
4) radne direktorijume (APLIKACIJE)
5) instrukcije programa (APLIKACIJE)
6) registre (...)
7) stack (...)
8) heap (...)
9) fajl deskriptore (...)
10) signal-akcije (...)
11) dinamicke biblioteke koje su ucitane (...)
12) i na kraju zna i za sve IPC stvari koje su aktivne u aplikaciji (message queues, pipes, semaphores, shared memory)

Za razliku od svega gore navedenog sto "krasi" proces, "nit" (svaka) radi NEZAVISNO i moze biti sinhronizovana zato jer ima:
1) svoj LICNI stack pointer
2) set registara
3) sve sto treba za "scheduling"
4) grupu "pending" i "blocked" signala
5) grupu svojih licnih podataka

Jedan proces moze imati vise niti, lepa osobina koja niti cini mocnim je da sve te niti DELE resurse (svoje) unutar procesa. Tako da:
1) izmene koje jedna nit napravi na bilo kom deljenom resursu (recimo varijabli) ce biti vidljive U SVIM DRUGIM nitima.
2) dva pokazivaca koji imaju istu vrednost pokazuju na ISTI podatak.
3) citanje/pisanje po istim memorijskim lokacija od strane vise niti je moguce i od programera se zahteva (ako je potrebno) da "odradi" sinhronizaciju.

Na kraju, primer fork()-a (koriscenje procesa):
Code:

#define NFORKS 50000

void do_nothing() {
int i;
i= 0;
}

int main() 
{
int pid, j, status;

for (j=0; j<NFORKS; j++) {

  /*** provera greske ***/
  if ((pid = fork()) < 0 ) {
    printf ("fork failed with error code= %d\n", pid);
    exit(0);
    }

  /*** ako je pid nula, onda je u pitanju dete-proces ***/
  else if (pid ==0) {
    do_nothing();
    exit(0);
    }

  /*** inace je u pitanju roditelj-proces ***/
  else {
    waitpid(pid, status, 0);
    }
  }
}  


I primer niti:
Code:

#include <pthread.h>

#define NTHREADS 50000

void *do_nothing(void *null) {
int i;
i=0;
pthread_exit(NULL);
}                      

main() {
int rc, i, j, detachstate;
pthread_t tid;
pthread_attr_t attr;

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

for (j=0; j<NTHREADS; j++) {
  rc = pthread_create(&tid, &attr, do_nothing, NULL);
  if (rc) {              
    printf("ERROR; povratni kod od pthread_create() je %d\n", rc);
    exit(-1);
    }

  /* cekan na nit da zavrsi posao */
  rc = pthread_join(tid, NULL);
  if (rc) {
    printf("ERROR; povratni kod od pthread_join() je %d\n", rc);
    exit(-1);
    }
  }

pthread_attr_destroy(&attr);
pthread_exit(NULL);

}


Za objasnjavanje drugog koda bi trebo jedan podugacak tekst, ovako cu samo reci sta radi pthread_join() - pthread_join() BLOKIRA thread u kome je pozvana (u ovom slucaju MAIN THREAD - main() funkcija je zapravo takozvani MAIN THREAD) dok nit sa ID-jem "tid" ne zavrsi svoj posao.

Druga stvar koju treba primetiti je da umesto ocekivanog exit() ili return() u main() funkciji imamo pthread_exit(NULL); :) Dakle iz MAIN THREAD-a izlazimo kao i iz bilo kojeg drugo, prema POSIX standardu - funkcijom pthread_exit();

E sada malo rezultata... - Gore navedene programe smo iskompajlirali i startovali:
Code:

bash$ gcc proc.c -o proc
bash$ time ./proc

real    0m9.866s
user    0m1.220s
sys     0m8.470s
bash$ gcc nit.c -o nit -lpthread
bash$ time ./nit

real    0m5.878s
user    0m0.590s
sys     0m5.210s


proc.c je prvi listing, nit.c je drugi listing. Rezultati govore sami za sebe.

[ boccio @ 11.12.2003. 11:59 ] @
...a tu se prica prosiruje na mutexe, semafore, kriticne sekcije...igranka bez prestanka :)
[ NikolaVeber @ 12.12.2003. 15:31 ] @
Hvala !

I sto bi reko Kojot : "back to the drawing board...."
[ dragisha @ 15.12.2003. 09:51 ] @
Citat:
boccio:
...a tu se prica prosiruje na mutexe, semafore, kriticne sekcije...igranka bez prestanka :)


mutex i kritična sekcija su cca isto.

Tri osnovna koncepta (i tipa objekata) su Thread, MUTEX i Condition. Thread je kako je Leka napisao laganiji proces a MUTEX i Condition su par za medjusobnu sinhronizaciju threadova. Neki jezici, poput Jave, to imaju sakriveno od korisnika, ali MUTEX i Condition su uvijek tu. Ostala sredstva sinhronizacije su sva izvedeni iz ta dva osnovna.