Playing with threads

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Playing with threads

Post by MrGodin » August 14th, 2017, 12:15 am

Well, here i go again ...
I've made a path finding manager to get a path via a thread.
It works, but is there any way it can go wrong ?.. I haven't tried it with a lot of instances. I am worried that there may be come sort of screw-up if there a lot of threads.
Manager Class (header)

Code: Select all

#pragma once

#include "newAStar.h"
#include <queue>
#include <memory>


class PathRequest
{
public:
	std::future<std::vector<Vec2f>> thread;
	class Actor* owner = nullptr;
	PathRequest() = default;

};

class PathfindingManager
{
private:
	std::vector<PathRequest*> m_queue;
	// for threading
	static MyAStar* m_pathFinder;
	static std::vector<Vec2f> _getPath(Vec2f start, Vec2f end);
public:
	PathfindingManager() = default;
	~PathfindingManager();
	PathfindingManager(vec_int_map map, Vec2f celldims);
	void requestPath(Vec2f start, Vec2f end, class Actor* owner);
	void checkForDone();
	
};
Cpp file

Code: Select all

#include "PathManager.h"
#include "GamePiece.h"

MyAStar* PathfindingManager::m_pathFinder = nullptr;
// function for thread
 std::vector<Vec2f> PathfindingManager::_getPath(Vec2f start, Vec2f end)
{
	return m_pathFinder->getPath(start, end);
}

PathfindingManager::~PathfindingManager()
{
	if (m_pathFinder)
		delete m_pathFinder;

	for (auto& it : m_queue)
		delete it;
}

PathfindingManager::PathfindingManager(vec_int_map map, Vec2f celldims)
{
	m_pathFinder = new MyAStar(map,celldims);
}

void PathfindingManager::requestPath(Vec2f start, Vec2f end, Actor * owner)
{
	PathRequest* req = new PathRequest;
	req->thread = std::async(_getPath, start, end);
	req->owner = owner;
	m_queue.push_back(req);

}

void PathfindingManager::checkForDone()
{
	if (m_queue.size() == 0)return;
	for (int i = 0; i < m_queue.size(); i++)
	{
		if (m_queue[i]->thread.valid())
		{
			std::vector<Vec2f> p = m_queue[i]->thread.get();
			if (p.size() > 0)
			{
				m_queue[i]->owner->SetPath(p);
				delete m_queue[i];
				m_queue.erase(m_queue.begin() + i);
				i--;
				
			}
		}
	}
}
Curiosity killed the cat, satisfaction brought him back

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Playing with threads

Post by MrGodin » August 14th, 2017, 2:20 am

Ok, so I ran a loop all accessing the path finding and it failed, sooo .. like a good little boy i used google and cplusplus.com and did this

Code: Select all

 std::vector<Vec2f> PathfindingManager::_getPath(Vec2f start, Vec2f end)
{
	 std::lock(lk1,lk2);
	 std::vector<Vec2f> path  =  m_pathFinder->getPath(start, end);
	 lk1.unlock();
	 lk2.unlock();
	 return path;
}
not sure why i need 2 mutex's but it works lol ;)
Curiosity killed the cat, satisfaction brought him back

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Playing with threads

Post by cameron » August 14th, 2017, 4:19 pm

There shouldn't be a reason why you would need two mutexes there. Unless those locks are used in other blocks of async code. The only thing I can think of is it might add enough delay to 'solve' a race condition.
Computer too slow? Consider running a VM on your toaster.

Post Reply