Есть класс CParallelBellmanFord, при вызове некоторого метода запускается N потоков с телом WorkerThread Код (Text): void CParallelBellmanFord::WorkerThread() { int rid; bool runFlag; char* section = "\0"; try { for(;;) { mMutex.Lock(); rid = -1; section = "Find region to update\0"; for(uint i = 0; i < mNumRegions; i++) { if(mRegions[i].update == 1) { mRegions[i].update = 0; rid = i; break; } } runFlag = mRunFlag; mMutex.Unlock(); if(!runFlag) return; if (rid < 0) { Sleep(10); continue; } section = "Process region\0"; SRegion& region = mRegions[rid]; if(ProcessRegion(region)) { mMutex.Lock(); section = "Mark all regions\0"; for(uint i = 0; i < mNumRegions; i++) mRegions[i].update = 1; mRegions[rid].update = 0; mMutex.Unlock(); } } } catch(const CException& ex) { FILE* f = fopen("WorkerThread.log", "a"); fprintf(f, "Exception: '%s' at '%s' line %d\nsection %s\n\n", ex.GetText(), ex.GetFile(), ex.GetLine(), section); fclose(f); } catch(...) { FILE* f = fopen("WorkerThread.log", "a"); fprintf(f, "Fatal error\nsection %s\n\n", section); fclose(f); } } bool CParallelBellmanFord::ProcessRegion(const SRegion& region) { bool flag = false; const uint numEdges = region.edges.GetCap(); const uint numVertices = region.numVertices; char* section = "\0"; uint di = 0; uint dj = 0; try { for(uint i = 0; i < numVertices; i++) { di = i; for(uint j = 0; j < numEdges; j++) { dj = j; section = "uint id = region.edges[j]\0"; uint id = region.edges[j]; section = "const SEdge& edge = mGraph->GetEdge(id)\0"; const SEdge& edge = mGraph->GetEdge(id); section = "if (mDistances[edge.src] >= MAX_INT)\0"; if (mDistances[edge.src] >= MAX_INT) continue; section = "int dist = mDistances[edge.src] + edge.weight\0"; int dist = mDistances[edge.src] + edge.weight; section = "if (dist >= mDistances[edge.dst])\0"; if (dist >= mDistances[edge.dst]) continue; section = "mDistances[edge.dst] = dist\0"; mDistances[edge.dst] = dist; section = "mPredcessor[edge.dst] = edge.src\0"; mPredcessor[edge.dst] = edge.src; flag = true; } } } catch(const CException& ex) { FILE* f = fopen("ProcessRegion.log", "a"); fprintf(f, "Exception: '%s' at '%s' line %d\nsection %s\n", ex.GetText(), ex.GetFile(), ex.GetLine(), section); fprintf(f, "numEdges=%d numVertices=%d\n", numEdges, numVertices); fprintf(f, "region.numEdges=%d region.numVertices=%d i=%d j=%d\n\n", region.edges.GetCap(), region.numVertices, di, dj); fclose(f); throw ex; } catch(...) { FILE* f = fopen("ProcessRegion.log", "a"); fprintf(f, "Fatal error\nsection %s\n\n", section); fclose(f); throw; } return flag; } Exception: 'id < mCap' at 'c:\projects\shortestpath\shortestpath\TArray.hpp' line 70 section uint id = region.edges[j] numEdges=22350 numVertices=11288 region.numEdges=11175 region.numVertices=5756 i=3335 j=11175 Exception: 'id < mCap' at 'c:\projects\shortestpath\shortestpath\TArray.hpp' line 70 section uint id = region.edges[j] numEdges=22350 numVertices=11362 region.numEdges=11175 region.numVertices=5756 i=3386 j=11175 Exception: 'id < mCap' at 'c:\projects\shortestpath\shortestpath\TArray.hpp' line 70 section uint id = region.edges[j] numEdges=11175 numVertices=5757 region.numEdges=7450 region.numVertices=3888 i=5595 j=7450 ------------------------------------------------- numEdges <> region.numEdges numVertices <> region.numVertices как такое возможно??? прочитали значения структуры в начале кода и что произошло в конце (учитывая, что переменные и структура не изменяются)...
Неправильно: Код (Text): char* section = "\0"; Правильно: Код (Text): const char* section = "\0"; Объект, для которого вызывается WorkerThread, один на все потоки, или уникален на каждый поток? Код (Text): SRegion& region = mRegions[rid]; Почему это не под мутексом?
Один класс - N потоков char* section = "\0"; это для отладки, значения не имеет SRegion& region = mRegions[rid]; т.к. rid уникален и другой поток взять его не может и массив mRegions не изменяется то по идее lock не нужен ProcessRegion тоже не лочится (т.к. для алгоритма не важно в каком порядке потоки прочитают и изменят данные). Что происходит, если несколько потоков пытаются изменить переменную одновременно? Мне кажется что такого в любом случае не должно происходить.