Opět zápasím s více vláknovou aplikací a potřeboval bych trochu poradit...
Jedná se o aplikaci, kde v mainu budu načítat nějaká data ze souboru a chci, aby se o jejich vyhodnocování starala vlákna (počet vláken je v rozmezí 1-50). Každé vlákno = jeden výpočet. Používám jeden semafor, který pouští počítací vlákna k datům a jeden mutex, který se stará, aby vlákna nepřistupovaly k paměti najednou. Příklady načtené ze souboru ukládán do spojového seznamu.
Pokud pocet_vlaken = 1, tak aplikace funguje. Problém nastane až když je vytvořeno více vláken. Vlákna příklady počítají rychleji, než je program stačí načítat ze souboru a vlákno se dostane k tomu, že nastavuje fronta = fronta->dalsi, ale dalsi je zatim NULL, protoze se to jeste nestačilo načíst.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t semafor;
pthread_mutex_t pristup;
typedef struct Fronta Fronta;
struct Fronta{
Fronta * dalsi;
};
typedef struct Data{
Fronta * fronta;
int delka;
int ukoncit;
int hotovo;
} Data;
void * pocitej(void * arg){
Data * data = (Data *) arg;
int out, val, i;
Fronta * priklad;
while (1){
sem_wait(&semafor);
pthread_mutex_lock(&pristup);
if (data->ukoncit == 1){
pthread_mutex_unlock(&pristup);
sem_post(&semafor);
break;
}
if (data->delka == 1 && data->hotovo != 1){
printf("Zasekl jsem se... Pomoc...\n");
break;
}
priklad = data->fronta;
data->fronta = data->fronta->dalsi;
data->delka = data->delka - 1;
printf("delam nejake vypocty... \n");
free(priklad);
if ((data->hotovo == 1 && data->delka == 0)){
data->ukoncit = 1;
pthread_mutex_unlock(&pristup);
sem_post(&semafor);
break;
}
pthread_mutex_unlock(&pristup);
}
printf("Koncim vlakno.\n");
return NULL;
}
int main(int argc, char ** argv){
pthread_attr_t attr;
int pocet_vlaken = 20;
int i, delka = 0;
Fronta * zacatek = (Fronta *) malloc(sizeof(Fronta));
Fronta * fronta = zacatek;
Fronta * novy;
Data * data = (Data *) malloc(sizeof(Data));
pthread_t * vlakna = (pthread_t *) malloc(pocet_vlaken * sizeof(pthread_t));
pthread_mutex_init(&pristup, NULL);
pthread_attr_init( &attr );
pthread_attr_setdetachstate ( &attr, PTHREAD_CREATE_JOINABLE );
sem_init(&semafor, 0, -1);
data->fronta = zacatek;
data->hotovo = 0;
data->ukoncit = 0;
data->delka = 0;
for (i = 0; i != pocet_vlaken; i++){
pthread_create (&vlakna[i], &attr, pocitej, (void *) data);
}
while (delka != 100){
pthread_mutex_lock(&pristup);
if (i == 0 && delka == 0){
novy = zacatek;
}
else{
novy = (Fronta *) malloc(sizeof(Fronta));
fronta->dalsi = novy;
}
fronta = novy;
data->delka = data->delka + 1;
pthread_mutex_unlock(&pristup);
sem_post(&semafor);
delka++;
}
data->hotovo = 1;
pthread_attr_destroy ( &attr );
for (i = 0; i < pocet_vlaken; i++){
pthread_join (vlakna[i], NULL);
}
free(vlakna);
free(data);
sem_destroy (&semafor);
pthread_mutex_destroy (&pristup);
}
Kde je chyba? S těmi vlákny si fakt moc nevím rady.
Budu vděčný za jakoukoli pomoc.