PathFinder icon indicating copy to clipboard operation
PathFinder copied to clipboard

Singleton-based approach breaks multi-threading.

Open sniggyfigbat opened this issue 3 years ago • 2 comments

As far as I can tell there is no reason why Path Algorithm specialisations need to be singletons; it provides no particular benefit (to AStar, anyway) and it prevents the library from working properly in multithreaded workloads. The fix is trivial, simply allowing the Pathfinder class to create a new instance of the algorithm class and using that (and making sure to call clear() before returning the found path).

sniggyfigbat avatar May 14 '21 21:05 sniggyfigbat

You're right there isn't a compelling reason for using singletons. I wouldn't write it this way nowadays :) I'm not actively maintaining this code anymore but feel free to propose a PR and I'll eventually merge it!

Sahnvour avatar May 15 '21 12:05 Sahnvour

I have to point out that Singletons aren't the only thing breaking multi-threading.

I looked into this but it would require deeper changes.

Right now each time the algorithm is run, the nodes themselves are modified; which breaks multithreading.

In other words the following routines (and more importantly the variables they modify) would have to be moved outside the node and kept somewhere else or in a way that is multithread-friendly:

  1. AStarNode::setOpen
  2. AStarNode::setClose
  3. AStarNode::setF
  4. AStarNode::setG
  5. AStarNode::setH
  6. Node::setParent

The least intrusive way I can think of is to have this data live in a std::vector<> where the size of the vector is the max number of threads:

class AStarNode : public Node
{
   struct PerThread
   {
		float m_f, m_g, m_h;
		bool open, closed;
   };

   std::vector<PerThread> t;
}

And modify all functions to use a thread idx (or use a global TLS).

Anyway, that is the least intrusive method I can think of and even then it requires a big rewrite.

Alternatively, you can just clone the nodes along with their child/parent relationships for every thread and thus the only thing you'd need to solve would be the singleton.

darksylinc avatar Apr 30 '23 18:04 darksylinc