Dans mon programme j'utilise un systeme producer�consumer avec une std::queue
Dans le thread je peut faire appel a chunksToLoad.pop(); par exemple mais pas � chunksToLoad.front(); qui fait crash
Version imprimable
Dans mon programme j'utilise un systeme producer�consumer avec une std::queue
Dans le thread je peut faire appel a chunksToLoad.pop(); par exemple mais pas � chunksToLoad.front(); qui fait crash
Bonjour,
Il nous faut plus d'info pour pouvoir t'aider.
Code:
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 #include "chunkLoading.h" #include "iostream" #include <SFML/Window.hpp> #include<chunk.h> using namespace std; ChunkLoading::ChunkLoading() { } ChunkLoading::ChunkLoading(World* world) { worldIn=world; for(int i=0;i<5;i++) for(int j=0;j<1;j++) for(int k=0;k<5;k++) { addChunkToLoad(ivec3(i,j,k)); } thread loadingThread(loadLoop,this); loadingThread.detach(); } ChunkLoading::~ChunkLoading() { //dtor } void ChunkLoading::loadChunk() { if(!chunksToLoad.empty()) { glm::ivec3 pos=chunksToLoad.front();//crash Chunk* p = new Chunk(pos,worldIn); worldIn->queueMutex.lock(); worldIn->sendChunk(p); worldIn->queueMutex.unlock(); chunksToLoad.pop(); } } void ChunkLoading::loadLoop() { while(!chunksToLoad.empty()) { sf::sleep(sf::milliseconds(100)); loadChunk(); } }
Il manque encore des infos. D'apr�s ce que je vois. A quoi �a sert un mutex? �a permet d�emp�cher que 2 threads agissent en m�me temps sur une m�me ressource. Ta fonction loadChunk() veut prot�ger l'appel � sendChunk(), c'est possible que �a soit n�cessaire, j'ai des doutes (divination sans voir le code). Par contre l'objet chunkToLoad est peut-�tre utilis� par plusieurs threads (divination sans voir le code), et dans ce cas il faut "prot�ger" les fonctions qui l'utilisent comme .empty() .front() et .pop(). Du coup, je "prot�gerais" exactement l'inverse de ce que tu as fait.
Code:
1
2
3
4
5
6
7
8
9
10
11
12 void ChunkLoading::loadChunk() { worldIn->queueMutex.lock(); if ( !chunksToLoad.empty() ) { glm::ivec3 pos = chunksToLoad.front();//crash worldIn->queueMutex.unlock(); Chunk* p = new Chunk( pos, worldIn ); worldIn->sendChunk( p ); worldIn->queueMutex.lock(); chunksToLoad.pop(); } worldIn->queueMutex.unlock(); }
chunksToLoad est une queue remplie au d�but du programme et destin� a �tre rempli au fur et a mesure par le thread,donc pas d�acc�s simultan�Code:
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 #include "world.h" #include <vector> #include <chunk.h> #include <iostream> using namespace glm; World::World() { ChunkLoading chunkLoader(this); } World::~World() { //dtor } void World::addChunks(){ queueMutex.lock(); while(!chunksLoaded.empty()) { Chunk* p=chunksLoaded.front(); chunksLoaded.pop(); chunkMap[p->Getpos()]=p; p->init(); } queueMutex.unlock(); } std::unordered_map<ivec3,Chunk*>::const_iterator World::getChunk(ivec3 pos){ return chunkMap.find(pos); } void World::sendChunk(Chunk* p){ chunksLoaded.push(p); }
tandis que chunksLoaded est une queue de chunks pr�charg�s rempli par le thread(via sendchunk) et consomm� par la boucle principale(via addChunks),c'est donc celui l� que j'ai prot�g�
Ligne 8, tu cr�es un ChunkLoading.
Dans le constructeur de ChunkLoading, tu lances un thread qui va utiliser le ChunkLoading.
Mais ligne 9, tu quittes le World::World() donc ton objet chunkLoader de type ChunkLoading dispara�t imm�diatement.
Quand le thread s�ex�cute, l'objet ChunkLoading est d�j� plus l� d'o� un plantage quand le thread veut y acc�der.
chunkLoader est membre de world donc il ne devrait pas disparaitreCode:
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 #ifndef World_H #define World_H #include <chunk.h> #include <chunkLoading.h> #include <unordered_map> #include <glm/glm.hpp> #define GLM_ENABLE_EXPERIMENTAL #include "glm/gtx/hash.hpp" #include <mutex> #include <queue> using namespace glm; class Chunk; class ChunkLoading; class World { public: World(); virtual ~World(); void addChunks(); void sendChunk(Chunk* p); std::unordered_map<ivec3,Chunk*>::const_iterator getChunk(ivec3 pos); std::unordered_map<ivec3,Chunk*>::const_iterator endOfMap(){return chunkMap.end();} std::unordered_map<ivec3,Chunk*> chunkMap; std::mutex queueMutex; private: ChunkLoading chunkLoader; std::queue<Chunk*> chunksLoaded; }; #endif // World_H
En ligne 8, vous d�clarez une variable locale et vous l'assignez. Ce n'est pas le champ/membre qui est utilis�.
Faites vous un cadeau, utilisez les listes d'initialisation. ;)