如何停止使用dispatch_async创建的线程? [英] How to stop a thread created with dispatch_async?
问题描述
如果dispatch_async
创建的线程使用了太多时间(例如超过5分钟),我想强行停止它.通过互联网搜索,我发现有人认为无法停止该线程,有人知道吗?
I want to forcibly stop the thread created by dispatch_async
if its in use for too much time, for example pass over 5 minutes. By searching over the internet, I got some one thought there was no way to stop the thread, does any one know that?
在我的想象中,我想创建一个NSTimer
以在指定的时间过去后停止线程.
In my imagine, I want to create a NSTimer
to stop the thread when time specified passed.
+ (void)stopThread:(NSTimer*)timer
{
forcibly stop the thread???
}
+ (void)runScript:(NSString *)scriptFilePath
{
[NSTimer scheduledTimerWithTimeInterval:5*60 target:self selector:@selector(stopThread:) userInfo:nil repeats:NO];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[LuaBridge runLuaFile:scriptFilePath];
});
}
我的runLuaScript方法:
My runLuaScript method:
+ (void)runLuaFile:(NSString *)filePath
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
int error2 = luaL_dofile(L, [filePath fileSystemRepresentation]);
if (error2) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
}
亲爱的@Martin R,我应该这样使用lstop吗?当我想停止线程时,只需调用stopLuaRunning
方法?
Dear @Martin R, should I use lstop like that, and when I want to stop the thread, just call stopLuaRunning
method?
static lua_State *L = NULL;
+ (void)runLuaFile:(NSString *)filePath
{
L = luaL_newstate();
luaL_openlibs(L);
int error2 = luaL_dofile(L, [filePath fileSystemRepresentation]);
if (error2) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
}
+ (void)stopLuaRunning:(lua_State *L)
{
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
推荐答案
您无法杀死正在运行的块.您必须以异步方式工作并可以取消的方式实现runLuaFile
.
You cannot kill a running block. You have to implement runLuaFile
in a way that it works asynchronously and can be cancelled.
例如,如果运行脚本是通过NSTask
完成的,则可以使用terminate
杀死
如果任务运行时间太长.
For example if running the script is done via NSTask
, you can use terminate
to kill
the task if it is running too long.
NSOperation
可能无济于事,因为cancel
依赖于要执行的操作
合作":必须定期检查操作是否已取消.那不会
停止正在运行的runLuaFile
方法.
NSOperation
will probably not help because cancel
relies on the operation to be
"cooperative": the operation has to check regularly if it has been cancelled. That will not
stop the running runLuaFile
method.
更新:通过检查Lua解释器的源代码"lua.c",似乎
我可以使用lua_sethook
取消正在运行的脚本.
UPDATE: From inspecting the source code "lua.c" of the Lua interpreter, it seems to
me that you can cancel a running script using lua_sethook
.
一个非常简单的实现(为Lua状态使用静态变量)将是:
A very simple implementation (using a static variable for the Lua state) would be:
static lua_State *L = NULL;
+ (void)runLuaFile:(NSString *)filePath
{
L = luaL_newstate();
luaL_openlibs(L);
int error2 = luaL_dofile(L, [filePath fileSystemRepresentation]);
if (error2) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
L = NULL;
}
static void lstop (lua_State *L, lua_Debug *ar)
{
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
+ (void)stopLuaRunning
{
if (L != NULL)
lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
更优雅的解决方案是将Lua状态存储在该类的实例变量中
并使用runLuaFile
和stopLuaRunning
实例方法代替类方法.
A more elegant solution would use store the Lua state in an instance variable of the class
and make runLuaFile
and stopLuaRunning
instance methods instead of class methods.
这篇关于如何停止使用dispatch_async创建的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!