I need help on multiple-thread

Hello guys,
I want to run two threads on the same script. I am able to run the first thread but the second thread could not execute. It gives me an error.

local function mainRoutine()
	while true do
		-- // INTERMISSION \\ --
		if isIntermission then
			for i = intermissionTime, 0, -1 do
				if #moduleScript.players.generalPlayers < minPlayer then
					warn("Game needs "..minPlayer.. " player(s) to start!")
					break
				end
				print("Intermission ("..i..")")
				task.wait(1)
			end
		end
		-- // MAP SELECTING \\ --
		if isMapSelecting then
			for i = mapSelectingTime, 0, -1 do
				if #moduleScript.players.generalPlayers < minPlayer then
					warn("Map phase needs "..minPlayer.. " player(s) to start!")
					break
				end
				print("Map selecting ("..i..")")
				task.wait(1)
			end
		end
		task.wait(1)
	end
end

local primaryThread = coroutine.create(mainRoutine)
local secondaryThread = coroutine.create(moduleScript.autoSave(5))

coroutine.resume(primaryThread)
coroutine.resume(secondaryThread)
function module:autoSave(amount: seconds)
	for i = amount, 0, -1 do
		task.wait(1)
		warn("Saving all players data in ("..i..")")
		for _, players in pairs(getPlayerService:GetPlayers()) do
			module.savePlayerData(players)
		end
	end
end
  18:01:52.764  ServerScriptService.ModuleScripts.playerFunctions:105: invalid 'for' initial value (number expected, got nil)  -  Server - playerFunctions:105
1 Like

This is an issue with colons :

2 options

Use module:autoSave(5) instead of module.autoSave(5) or

Redefine autosave to function module.autoSave(amount: seconds)

Should you wish to start the threads immediately, remember task.spawn can be used instead of coroutine.create as it does not need .resume to start the thread

1 Like

hello there. I have fixed the issue with your guidance. Now the code looks like this

	local primaryThread = task.spawn(main)
	local secondaryThread = task.spawn(moduleScript:autoSave(autoSaveThreshold))
function module:autoSave(seconds)
	while true do
		for i = seconds, 0, -1 do
			if #getPlayerService:GetPlayers() > 0 then
				break
			end
			task.wait(1)
			print("Saving all players data in ("..i..")")
			
			if i <= 0 then
				for _, players in pairs(getPlayerService:GetPlayers()) do
					module:savePlayerData(players)
				end
			end
		end
		task.wait(1)
	end
end

Output

  19:56:43.930  Game needs 2 player(s) to start!  -  Server - GameManager:27
  19:56:43.930  autoSave failed due to insuffient player(s)  -  Server - playerFunctions:110
2 Likes

But let’s say if I want more control over the thread. Does task.spawn allow me to delay or resume? I’m clueless on these types of things.

task.spawn returns a thread. so does coroutine.create. so most coroutine methods can be used on a thread returned by task.spawn so you can still use coroutine.resume etc on it

task.cancel(threadname) can stop the thread permanently

coroutine.status(threadname) can tell you if the thread is running, finished (dead), ‘suspended’ or ‘normal’

Both of these are incorrect formats for coroutine.create and task.spawn, because what you are doing in those cases is calling the function immediately and then creating the thread with the return value.


Instead, you can pass arguments to coroutine and spawn like so

task.spawn(someFunction, someArgument1, someArgument2)
-- this works the same with module scripts
task.spawn(module.someFunction, someArg1, someArge2)

Since you’re using colon, you have to manually send through the self variable which would just be the module

task.spawn(moduleScirpt.autoSave, moduleScript, 5)