Reputation: 431
I've created a game in VS2010 using VB .NET 4 in C#. The game creates a thread for each player, and runs LUA code that the players have created.
Each LUA code is blocking for the thread, and should only terminate when the thread is terminated (The LUA script should contain an infinite loop)
I want to limit the CPU usage as the computer is currently overheating after running with 100% CPU for a few hours.
How can I throttle the threads without having control within them? I was hoping to have a thread manager to force suspend/resume but those are becoming obsolete, and I don't want to be throwing exceptions because that will abort my LUA code that's executing.
Any ideas?
Thanks!
Upvotes: 3
Views: 3794
Reputation: 12540
The classic way to gain control of the scheduling of threads of execution is to use Fibers.
However, Fibers are a native feature of the WIN32 API....the nearest you can come in C# is to use iterators...where you do bits of work inbetween each yield....but you decide when you want the next bit of work to be done by calling the iterator.
See 2nd link...might be a way to use the unmanaged native Fibre API to wrap some .NET coroutines, or if the LUA code you are running in this thread is native and you don't have access to the source code...then you might be able to use ConvertThreadToFibre to gain control of it (and decide when it gets scheduled using some interop to the Fiber API calls).
http://paoloseverini.wordpress.com/2012/02/02/implementing-iterator-blocks-in-c-part-2-win32-fibers/
http://www.altdevblogaday.com/2011/05/25/implementing-fibers-in-c/
http://www.altdevblogaday.com/2011/02/01/slim-and-light-multitasking-with-fibers/
Fibers in C#: are they faster than iterators, and have people used them?
Or you could have a scheduling thread which uses Events to signal to the player threads when they can continue and do some work (if some of your code is native/C++ and some is C# then each can refer to the same Event handles....just use the WIN32API or .NET API in each bit of code).
Upvotes: 1
Reputation: 123642
You can set the thread priority to low for those threads - that would help your system remain responsive... but you'd still use 100% CPU and still overheat, so I won't go into detail of how.
As other posters have mentioned, you need to get your threads to insert small sleeps. If you have no control over them at all, you can't do anything else.
I'd suggest you need to change your game API.
Rather than having your code call the Lua code one time, and then Lua code infinite looping, I'd suggest you make the Lua code have a "Run one frame" function. You then move the infinite loop into your own code, and repeatedly call the "Run one frame" function.
That way, you can insert sleeps, add logging, and do all kinds of other useful things.
Upvotes: 7
Reputation: 8206
The typical way to make sure a thread in an infinite loop doesn't consume too much cpu is to make it sleep a little in each iteration (5 ms will usually do the trick). This will give the system time to allow other resources to use the cpu. Also, do not give threads Highest Priority.
Upvotes: 1