如何停止使用dispatch_async创建的线程? [英] How to stop a thread created with dispatch_async?

查看:570
本文介绍了如何停止使用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状态存储在该类的实例变量中 并使用runLuaFilestopLuaRunning实例方法代替类方法.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆