In the Lua script call, if we encounter a Bad script, for example:
While 1 do
Do
End
Then ourProgramThe main thread will also be blocked. So how can we prevent this problem? Here is a solution.
First, in order not to block the main thread, we need to open a thread to put all the operations for processing the script in this new working thread. (For details about the differences and management between working threads and interface threads, please refer to my own article.ArticleBlog in Windows Programming 《Windows Thread-interface thread and worker thread).
Overall Thinking:
1. Start the thread to execute script parsing. The following is startrun ()
2. Export a function to determine whether or not to end, so that each cycle of the script is called to determine whether the thread should end. The function is isthreadexit () below (), returns a string ("exit" indicates that the while loop is over, and "notexit" indicates that the thread cannot end)
3. If the main thread needs to actively end the thread, it will call stoprun ()
4. It is best to export a ysleep pause function to avoid high CPU usage because the while loop runs too fast.
In this way, the Lua script becomes the following form:
While 1 do
Exitthread = isthreadexit ();
Ysleep (100 );
If exitthread = "exit" then
Break;
End;
End;
VCCodeThe output is an output function, which can be replaced by MessageBox:
// Global variable
// Indicates whether the thread is to end
Bool g_bexitdofile = false;
// Thread handle
Handle g_hdofile = NULL;
// Function to be exported
// Let Lua determine whether the loop can exit
Static int isthreadexit (lua_state * l)
{
If (g_bexitdofile)
Lua_pushlstring (L, "exit", 4 );
Else
Lua_pushlstring (L, "notexit", 7 );
// Return Value
Return 1;
}
// Pause function
Int ysleep (lua_state * l)
{
Int d = lual_checkinteger (L, 1 );
Sleep (d );
Return 0;
}
// Register the above functions
Int regfunc ()
{
Lua_pushcfunction (g_plua, isthreadexit );
Lua_setglobal (g_plua, "isthreadexit ");
Lua_pushcfunction (g_plua, ysleep );
Lua_setglobal (g_plua, "ysleep ");
Return 0;
}
// Thread Functions
DWORD winapi dofilethread (lpvoid lpparam)
{
Lpctstr strfilepath = (lpctstr) lpparam;
Lual_dofile (g_plua, strfilepath );
Stackdump (g_plua );
Return 0;
}
// Thread startup
Int startrun (lpctstr strfilepath)
{
// Register all functions to be exported
Regfunc ();
If (g_hdofile = NULL)
{
// Create a thread to execute the Lua script
G_hdofile = createthread (null, 0, dofilethread, (lpvoid) strfilepath, 0, null );
}
Else
{
Output ("Please call stoprun ()");
}
Return 0;
}
// Stop the thread
Int stoprun ()
{
// If the thread is running
If (g_hdofile)
{
// Loop LuaEnd Signal
G_bexitdofile = true;
// Wait for the thread to exit
DWORD dwret = waitforsingleobject (g_hdofile, infinite );
// Exit smoothly
If (dwret = wait_object_0)
{
Closehandle (g_hdofile );
G_hdofile = NULL;
G_bexitdofile = false;
Output ("dofile thread exited! ");
}
// Otherwise, the thread will be killed.
Else
{
DWORD dwexitcode;
Getexitcodethread (g_hdofile, & dwexitcode );
Terminatethread (g_hdofile, dwexitcode );
G_hdofile = NULL;
G_bexitdofile = false;
Output ("dofile thread was killed! ");
}
}
Return 0;
}
The above method uses the characteristics of the thread to solve the problem of script blocking. You can also use the hooks mechanism of Lua to prevent script blocking. This method will be discussed later...