Synchronizace více vláken – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Synchronizace více vláken – C / C++ – Fórum – Programujte.comSynchronizace více vláken – C / C++ – Fórum – Programujte.com

 

Blujacker
~ Moderátor
0
Grafoman
10. 3. 2011   #1
-
0
-

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.

Nahlásit jako SPAM
IP: 88.100.163.–
Navštivte server Matematika pro každého
Najdete zde články zabývající se matematikou základních a středních škol a databázi hlavolamů.
Pro vyzkoušení Vaš
Quiark0
Věrný člen
10. 3. 2011   #2
-
0
-

Klasický problém readers-writers (nebo taky producer-consumer) zámku. Na internetu (např. wikipedii) najdeš jak se to obvykle řeší.

Nahlásit jako SPAM
IP: 94.112.108.–
nervak0
Věrný člen
11. 3. 2011   #3
-
0
-

Špatně tu frontu plníš (a špatně inicializuješ semafor, špatně používáš mutex a ty flagy jsou k ničemu), jinak její vyprázdnění ničemu nevadí.

Nahlásit jako SPAM
IP: 213.211.51.–
nervak0
Věrný člen
11. 3. 2011   #4
-
0
-

To Quiark : Ani jedno.

Nahlásit jako SPAM
IP: 213.211.51.–
nervak0
Věrný člen
11. 3. 2011   #5
-
0
-

...

Nahlásit jako SPAM
IP: 213.211.51.–
Blujacker
~ Moderátor
0
Grafoman
11. 3. 2011   #6
-
0
-

To nervak : Díky, tenhle kod už fungoval. Sice tam byla ještě jedna chybka, který si všimnul až valgrind, ale jinak bezva, díky

Nahlásit jako SPAM
IP: 88.100.163.–
Navštivte server Matematika pro každého
Najdete zde články zabývající se matematikou základních a středních škol a databázi hlavolamů.
Pro vyzkoušení Vaš
Blujacker
~ Moderátor
0
Grafoman
11. 3. 2011   #7
-
0
-

To nervak : Díky, tenhle kod už fungoval. Sice tam byla ještě jedna chybka, který si všimnul až valgrind, ale jinak bezva, díky

Nahlásit jako SPAM
IP: 88.100.163.–
Navštivte server Matematika pro každého
Najdete zde články zabývající se matematikou základních a středních škol a databázi hlavolamů.
Pro vyzkoušení Vaš
nervak0
Věrný člen
12. 3. 2011   #8
-
0
-

Jaká chybka?

Nahlásit jako SPAM
IP: 213.211.51.–
nervak0
Věrný člen
12. 3. 2011   #9
-
0
-

Aha, už to vidím. Fujtajbl :)

Nahlásit jako SPAM
IP: 213.211.51.–
Blujacker
~ Moderátor
0
Grafoman
12. 3. 2011   #10
-
0
-

a ještě jedna drobnost. malloc vrací ukazatel na void, takže by se to mělo přetypovat ne? například



pthread_t * vlakna = (pthread_t *) malloc(threads*sizeof(pthread_t));

Nahlásit jako SPAM
IP: 88.100.163.–
Navštivte server Matematika pro každého
Najdete zde články zabývající se matematikou základních a středních škol a databázi hlavolamů.
Pro vyzkoušení Vaš
KIIV
~ Moderátor
+43
God of flame
12. 3. 2011   #11
-
0
-

To Blujacker : v C ti to nejspis v klidu projde (maximalne warning).. ale v C++ je to tusim nutnost pretypovat

Nahlásit jako SPAM
IP: 94.142.234.–
Program vždy dělá to co naprogramujete, ne to co chcete...
nervak0
Věrný člen
Nahlásit jako SPAM
IP: 213.211.51.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 18 hostů

Podobná vlákna

Více vláken — založil Václav Valíček

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý