Thread-uri in C/C++
Un program de test care lucreaza cu thread-uri in C/C++.
Pentru a putea rula programul este nevoie de gcc (pe Linux acesta se gaseste implicit)
Functia
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
creaza un fir de executie care se executa in paralel cu firul creator.
- Functia returneaza 0 in caz de succes si un numar negativ in caz contrar (codul de eroare)
- Parametrul start_routine este pointer spre functia care va fi executata de thread.
Parametrul start_routine este un pointer spre o functie care returneaza un pointer void* si primeste ca parametru tot un pointer void*. Acest lucru ne permite sa dam orice ca parametru si sa returnam orice. In exemplul nostru functia primeste ca parametru un pointer spre o valoare int. - Parametrul arg este valoarea cu care va fi apelata functia data ca parametru. Acest parametru poate sa fie NULL daca functia nu primeste nici un parametru.
- La adresa indicata de thread vor fi stocate informatii pentru identificarea thread-ului.
- Parametrul attr permite setarea unor atribute pentru thread. NULL inseamna atributele implicite.
Cu ajutorul functiei
int pthread_join(pthread_t th, void **thread_return);
putem astepta terminarea thread-ului th dat ca parametru si putem capta valoarea returnata de functia executata de thread la adresa thread_return
In codul din exemplu nu avem lock-uri deoarece toate thread-urile lucreaza cu date diferite.
Pentru compilare se ruleaza din directorul in care se afla fisierul sursa pthreadtest.c comanda:
gcc -D_REENTRANT -lpthread -Wall -o run pthreadtest.c
Pentru a rula programul:
./run
// pthreadtest.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define N 3
#define NR_FIRE 6
int fin;
void fa_ceva_lung() {
int i, j;
for(i=0; i<2000; i++) {
for(j=0; j<2000; j++);
}
}
void *fir_scriere(void *param) {
int i, val;
int* pval = (int*)param;
val = (int) *pval;
for(i=0; i<N; i++) {
fa_ceva_lung(); // sa nu se execute totul asa rapid
printf("firul %d...\n", val);
}
fin = 1;
return NULL;
}
int main(int argc, char **argv) {
pthread_t t[NR_FIRE];
int p[NR_FIRE];
int i;
// initializare parametrii
for(i=0; i<NR_FIRE; i++)
p[i] = i;
// sunt create thread-urile
for(i=0; i<NR_FIRE; i++) {
pthread_create(t+i, NULL, fir_scriere, (void*)(p+i));
}
// aici este codul din thread-ul parinte
while(fin == 0) {
printf("main-ul...\n");
fa_ceva_lung(); // sa nu se execute prea rapid
}
// se asteapta incheierea tuturor firelor de executie
for(i=0; i<NR_FIRE; i++) {
pthread_join(t[i], NULL);
}
// iesire program
exit(0);
scanf("%d" ,&i);
return 0; // succes
}