ios - 如何停止使用dispatch_async创建的线程?

标签 ios objective-c multithreading nstimer

我想强行停止dispatch_async创建的线程,如果它使用了太多时间,例如超过5分钟。通过互联网搜索,我发现有人认为无法停止该线程,有人知道吗?

在我的想象中,我想创建一个NSTimer来在指定的时间过去后停止线程。

+ (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方法:
+ (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方法?
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

例如,如果运行脚本是通过NSTask完成的,则可以使用terminate杀死
如果任务运行时间过长。
NSOperation可能无济于事,因为cancel依赖于要执行的操作
“合作”:必须定期检查操作是否已取消。那不会
停止正在运行的runLuaFile方法。

更新:通过检查Lua解释器的源代码“lua.c”,似乎
我可以使用lua_sethook取消正在运行的脚本。

一个非常简单的实现(将静态变量用于Lua状态)将是:

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实例方法而不是类方法。

关于ios - 如何停止使用dispatch_async创建的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17671828/

相关文章:

ios 在应用程序中访问负载配置文件

ios - 自定义相机 iOS

ios - 在 heightForRowAtIndexPath 中调用函数时无限循环

c++ - 如何在 Qt 中高效显示 OpenCV 视频?

ios - 为什么将键盘类型 "decimal pad "从应用程序更改为另一个?

ios - objective-c 在用户调用电话时静音UILocalNotification

ios - 从 `UIView` 获取类的实例

Java多线程-主线程停止

Php:何时使用 pthread

javascript - 点击在 iPhone 中不起作用