Multithreading. Creating a task hangs the game.

Greetings. I’m trying to create a task and do it like this:


MultithreadTestEvents.Add(TGraphTask<FMyTestTask>::CreateTask().ConstructAndDispatchWhenReady());

Here MultithreadTestEvents is a global array.

It works. But if I create this tasks in a loop, it will freeze my game until all tasks not finished. One more interesting thing - for 2 tasks all works fine. For 3 or more - hangs. I put a breakpoint and saw that my tasks are run in separate threads (not in GameThread).

Very odd. Can you post the implementation of your actual task objects?

Yes, it’s pretty strightforward:


class FMyTestTask
{
public:

	static ESubsequentsMode::Type GetSubsequentsMode()
	{
		return ESubsequentsMode::TrackSubsequents;
	}

	FORCEINLINE static TStatId GetStatId()
	{
		RETURN_QUICK_DECLARE_CYCLE_STAT(FMyTestTask, STATGROUP_TaskGraphTasks);
	}

	static ENamedThreads::Type GetDesiredThread()
	{
		return ENamedThreads::AnyThread;
	}

	void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent)
	{
		for (long unsigned int i = 0; i < 10e7; i++){
			int t = FMath::Sin(i);
			
		}
	}
};

As you can see the task is very long. I found on udn forums that you don’t recommend to use GraphTask for long running tasks. But why 2 runs normally and 3 - not?

Ah ok, yes, this is a bad idea.

This is what’s happening: The task graph system will create a worker thread for every CPU core available in your PC. Three of the threads are reserved for GameThread, RenderThread and StatsThread respectively. Your task uses AnyThread for the desired worker thread, which means that the task graph system may push your tasks to any of the worker threads. When you create a sufficient number of tasks, one or more of these will eventually be pushed to the GameThread, and therefore the game thread will be blocked until your task is finished.

For long running tasks you may consider creating your own thread instead. Take a look at the FRunnable / FRunnableThread API.

Thank you. It’s clear now.