如果我启动多个其他线程,多线程不起作用

时间:2017-04-14 13:41:12

标签: c# multithreading unity3d

我不知道这个问题是否特定于Unity,所以也许其他C#开发人员也可以帮助我:)

所以我实际上试图实现我自己的A *算法版本并提高性能我希望每个搜索者的实际路径查找都是多线程的:

One active seeker

直到我激活第二个导引头的那一刻,它的效果非常好: Two active seekers

就像你可以看到它在15次迭代后停止(根据我调用的文本输出的数量而变化 - >我猜线程在一段时间之后被杀死)并且第一个启动的线程被杀死了通过以下内容。

我正在使用C#ThreadPool类进行线程管理,但我也尝试使用Thread类。这是相同的结果。

我的线程的实现:

public static void RequestPath(PathRequest _request)
{
    Debug.Log("Queueing PathRequest...");
    ThreadPool.QueueUserWorkItem(instance.StartThreadedPathfinding, _request);
}

被叫方法:

private void StartThreadedPathfinding(object _stateInfo)
{
    PathRequest request = (PathRequest)_stateInfo;
    m_pathfinder.FindPath(request, OnPathFound);
}

FindPath

public void FindPath(PathRequest _request, Action<PathResult> _callback)
{
    Debug.Log("Starting A* Algorithm");
    BinaryHeap<Node> openList = new BinaryHeap<Node>(GridSize);
    HashSet<Node> closedList = new HashSet<Node>();

    Node startNode = _request.Start;
    Node targetNode = _request.Target;

    bool success = false;

    openList.Add(startNode);

    while (openList.Count > 0)
    {
        Debug.Log(Thread.CurrentThread.ManagedThreadId + ": " + Thread.CurrentThread.ThreadState.ToString());
        Node currentNode = openList.RemoveFirst();

        if (currentNode == targetNode)
        {
            // TODO: Path found -> _callback
            success = true;
            Debug.Log("Path found");
            _callback(new PathResult(null, success, _request.Callback));
            return;
        }

        closedList.Add(currentNode);

        foreach (Node neighbour in currentNode.m_neighbours)
        {
            if (closedList.Contains(neighbour))
            {
                continue;
            }

            int tentativeG = currentNode.m_gCost + GetDistance(currentNode, neighbour);
            if (openList.Contains(neighbour) && tentativeG > neighbour.m_gCost)
            {
                continue;
            }

            neighbour.m_parent = currentNode;
            neighbour.m_gCost = tentativeG;
            neighbour.m_hCost = GetDistance(neighbour, targetNode);

            if (openList.Contains(neighbour))
            {
                openList.UpdateItem(neighbour);
            }
            else
            {
                openList.Add(neighbour);
            }
        }
    }

    // TODO: No path to the target exists -> calculate some path
    success = false;
    Debug.Log("No existing path");
    _callback(new PathResult(null, success, _request.Callback));
    return;
}

RequestPathStartThreadedPathfinding位于名为PathRequestManager的班级中,FindPath位于名为Pathfinder的其他班级中。

另一点是,线程不会因为错误而停止,或者像那样但是仍然以某种方式运行我认为因为我在Unity中启动场景之后我必须在任务管理器中杀死Unity进程因为......卡住(当我必须这样做时,CPU负载总是大约80%) 想到死锁但找不到任何东西。

如果有人可以帮助我,我很高兴如果您需要有关源代码的更多信息,请随时询问:)

1 个答案:

答案 0 :(得分:0)

所以我发现问题归功于Unity forums中的答案:

我正在使用相同的Grid,因此在每个帖子的同一Nodes上工作。当我在一个线程上更新算法中的Node而另一个线程正在使用相同的Node时,会发生一些不好的事情,结果可以在问题的上方看到。

我通过克隆每个线程的网格并处理线程拥有的网格来解决这个问题。