Vlákna a semafory – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Vlákna a semafory – C / C++ – Fórum – Programujte.comVlákna a semafory – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Blujacker
~ Moderátor
0
Grafoman
28. 2. 2011   #1
-
0
-

Ahoj,

pracuji na vícevláknové aplikaci a narazil jsem na problém v následujícím kódu. Funkce pocitej nedela vlastne nic jineho, nez ze zvetsi ukazatel o jednicku a precte z pole[ukazatel]. Je tam i semaphor, aby si vlákna nemohla měnit hodnotu data->ukazatel, ale i přesto to nefunguje.





#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
sem_t mutex;

typedef struct DATA{
int ukazatel;
int ** pole;
} DATA;
void * pocitej(void * arg){
DATA * data = (DATA *) arg;
int * cislo;
while (1){
sem_wait(&mutex);
cislo = data->pole[data->ukazatel];
data->ukazatel = data->ukazatel + 1;

if (data->ukazatel > 100){
sem_post(&mutex);
break;
}
sem_post(&mutex);

}
return NULL;
}
void vlakna(int threads){
int ** pole = (int **)malloc(101 * sizeof(int *));
int i;
int * cislo;
pthread_t ** vlakna = (pthread_t **) malloc(threads * sizeof(pthread_t *));
pthread_attr_t attr;
sem_init(&mutex, 0, 1);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i = 0; i != 100; i++){
pole[i] = (int *) malloc(sizeof(int));
(*pole[i]) = i;
}
pole[i] = NULL;
DATA * data = (DATA *) malloc(sizeof(DATA));
data->ukazatel = 0;
data->pole = pole;
for (i = 0; i != threads; i++){
vlakna[i] = (pthread_t *) malloc(sizeof(pthread_t));
pthread_create(vlakna[i], &attr, pocitej, (void *) data);
}
for (i = 0; i != threads; i++){
pthread_join(*(vlakna[i]), NULL);
}
for (i = 0; i != 100; i++){
free(pole[i]);
}
free(pole);
for (i = 0; i != threads; i++){
free(vlakna[i]);
}
free(vlakna);
free(data);
pthread_attr_destroy(&attr);
}
int main(int argc, char *argv[]){
vlakna(5);
return 1;
}

Zkompiluju:


gcc -o a.out test.c -lpthread -lrt

spustím:


valgrind ./a.out


A výstup je:


==29337== Memcheck, a memory error detector
==29337== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==29337== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==29337== Command: ./a.out
==29337==
==29337== Thread 3:
==29337== Invalid read of size 8
==29337== at 0x4008DA: pocitej (in /home/jakub/prog/osy1/a.out)
==29337== Address 0x55d6368 is 0 bytes after a block of size 808 alloc'd
==29337== at 0x4C2815C: malloc (vg_replace_malloc.c:236)
==29337== by 0x400942: vlakna (in /home/jakub/prog/osy1/a.out)
==29337== by 0x400B66: main (in /home/jakub/prog/osy1/a.out)
==29337==
==29337==
==29337== HEAP SUMMARY:
==29337== in use at exit: 0 bytes in 0 blocks
==29337== total heap usage: 113 allocs, 113 frees, 2,664 bytes allocated
==29337==
==29337== All heap blocks were freed -- no leaks are possible
==29337==
==29337== For counts of detected and suppressed errors, rerun with: -v
==29337== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 4 from 4)


Kde je chyba? :)

Ahoj,

pracuji na vícevláknové aplikaci a narazil jsem na problém v následujícím kódu. Funkce pocitej nedela vlastne nic jineho, nez ze zvetsi ukazatel o jednicku a precte z pole[ukazatel]. Je tam i semaphor, aby si vlákna nemohla měnit hodnotu data->ukazatel, ale i přesto to nefunguje.





#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
sem_t mutex;

typedef struct DATA{
int ukazatel;
int ** pole;
} DATA;
void * pocitej(void * arg){
DATA * data = (DATA *) arg;
int * cislo;
while (1){
sem_wait(&mutex);
cislo = data->pole[data->ukazatel];
data->ukazatel = data->ukazatel + 1;

if (data->ukazatel > 100){
sem_post(&mutex);
break;
}
sem_post(&mutex);

}
return NULL;
}
void vlakna(int threads){
int ** pole = (int **)malloc(101 * sizeof(int *));
int i;
int * cislo;
pthread_t ** vlakna = (pthread_t **) malloc(threads * sizeof(pthread_t *));
pthread_attr_t attr;
sem_init(&mutex, 0, 1);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i = 0; i != 100; i++){
pole[i] = (int *) malloc(sizeof(int));
(*pole[i]) = i;
}
pole[i] = NULL;
DATA * data = (DATA *) malloc(sizeof(DATA));
data->ukazatel = 0;
data->pole = pole;
for (i = 0; i != threads; i++){
vlakna[i] = (pthread_t *) malloc(sizeof(pthread_t));
pthread_create(vlakna[i], &attr, pocitej, (void *) data);
}
for (i = 0; i != threads; i++){
pthread_join(*(vlakna[i]), NULL);
}
for (i = 0; i != 100; i++){
free(pole[i]);
}
free(pole);
for (i = 0; i != threads; i++){
free(vlakna[i]);
}
free(vlakna);
free(data);
pthread_attr_destroy(&attr);
}
int main(int argc, char *argv[]){
vlakna(5);
return 1;
}

Zkompiluju:


gcc -o a.out test.c -lpthread -lrt

spustím:


valgrind ./a.out


A výstup je:


==29337== Memcheck, a memory error detector
==29337== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==29337== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==29337== Command: ./a.out
==29337==
==29337== Thread 3:
==29337== Invalid read of size 8
==29337== at 0x4008DA: pocitej (in /home/jakub/prog/osy1/a.out)
==29337== Address 0x55d6368 is 0 bytes after a block of size 808 alloc'd
==29337== at 0x4C2815C: malloc (vg_replace_malloc.c:236)
==29337== by 0x400942: vlakna (in /home/jakub/prog/osy1/a.out)
==29337== by 0x400B66: main (in /home/jakub/prog/osy1/a.out)
==29337==
==29337==
==29337== HEAP SUMMARY:
==29337== in use at exit: 0 bytes in 0 blocks
==29337== total heap usage: 113 allocs, 113 frees, 2,664 bytes allocated
==29337==
==29337== All heap blocks were freed -- no leaks are possible
==29337==
==29337== For counts of detected and suppressed errors, rerun with: -v
==29337== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 4 from 4)


Všiml jsem si, že pokud upravím funkci pocitej:


...
if (data->ukazatel > 101-pocet_vlaken){
...

tak to funguje...


Kde je chyba

Děkuji

Nahlásit jako SPAM
IP: 85.161.157.–
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š
Reklama
Reklama
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, 44 hostů

Podobná vlákna

Vlákna a semafory — založil Blujacker

Vlakna — založil insider

Vlákna — založil blackman.ce

Vlákna — založil delphak

Vlakna — založil Homer

Moderátoři diskuze

 

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