Ik heb C++ in de titel gezet, maar de taal zou volgens mij niet echt uit moeten maken. Anyway, ik ben bezig met het onder de knie krijgen van concurrency en heb nu een basis idee bedacht waarbij een vast aantal threads een directorystructuur doorzoeken. Iedere thread leest een directory, en voegt iedere nieuw gevonden directory toe aan de workqueue. Zodra dit klaar is moeten de threads stoppen, joinen en is het programma rond.
In mijn hoofd leek het zo makkelijk
Dit is wat ik nu heb:
Toen ik dit bericht aan het schrijven was ontdekte ik al de oorzaak van een deadlock waarom ik dit topic wilde maken, (niet de eerste keer dat dat gebeurd
), regel 41 ontbrak nog, maar ik ben toch nog wat onzeker over de code.
Ik meen ook daarna nog een deadlock gehad te hebben toen ik dit zonder debugger draaide, maar na diverse pogingen met grote en kleine hoeveelheden threads en directories krijg ik dat niet geproduceerd, ook niet na het toevoegen van wat sleep calls in GetWorkItem(). Nu ga ik dus aan mezelf twijfelen, maar misschien dat iemand hier een mogelijkheid voor een deadlock ziet?
Ook ben ik geïnteresseerd in jullie meningen. Is dit een goede implementatie van een Work Queue? Ik heb het grofweg gebaseerd op Multithreaded Work Queue in C++, met dus de toevoeging dat threads zelf items in de work queue zetten en een flag zetten als het werk gedaan is. Wat zijn jullie ideeën hierover?
In mijn hoofd leek het zo makkelijk
Dit is wat ik nu heb:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| void ThreadManager::iAmRunning( ) { pthread_mutex_lock( &this->thread_mutex ); if( this->waitingthreads > 0 ) this->waitingthreads--; this->runningthreads++; this->all_work_done = false; pthread_mutex_unlock( &this->thread_mutex ); } void ThreadManager::iAmWaiting( ) { pthread_mutex_lock( &this->thread_mutex ); if( this->runningthreads > 0 ) this->runningthreads--; this->waitingthreads++; if( this->waitingthreads >= NUM_THREADS ) { this->all_work_done = true; pthread_cond_broadcast( &this->work_done_cond ); } else this->all_work_done = false; pthread_mutex_unlock(&this->thread_mutex); } Directory* ThreadManager::GetWorkItem() { this->iAmWaiting( ); pthread_mutex_lock( &this->directory_mutex ); while( this->workqueue.size() == 0 ) { if (this->all_work_done) { pthread_mutex_unlock(&this->directory_mutex); return NULL; } pthread_cond_wait( &this->work_done_cond, &this->directory_mutex ); } this->iAmRunning( ); Directory* ret = this->workqueue.back(); this->workqueue.pop_back(); pthread_mutex_unlock( &this->directory_mutex ); return ret; } |
Toen ik dit bericht aan het schrijven was ontdekte ik al de oorzaak van een deadlock waarom ik dit topic wilde maken, (niet de eerste keer dat dat gebeurd
Ik meen ook daarna nog een deadlock gehad te hebben toen ik dit zonder debugger draaide, maar na diverse pogingen met grote en kleine hoeveelheden threads en directories krijg ik dat niet geproduceerd, ook niet na het toevoegen van wat sleep calls in GetWorkItem(). Nu ga ik dus aan mezelf twijfelen, maar misschien dat iemand hier een mogelijkheid voor een deadlock ziet?
Ook ben ik geïnteresseerd in jullie meningen. Is dit een goede implementatie van een Work Queue? Ik heb het grofweg gebaseerd op Multithreaded Work Queue in C++, met dus de toevoeging dat threads zelf items in de work queue zetten en een flag zetten als het werk gedaan is. Wat zijn jullie ideeën hierover?
It might sound as if I have no clue what I'm doing, but I actually have a vague idea.