我想强行停止创建线程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);
}
亲爱的@马丁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状态的类的实例变量,并runLuaFile
和stopLuaRunning
实例方法,而不是类的方法。
您应该使用NSOperation
和NSOperationQueue
,因为他们已经内置支持取消使您的操作可以检查它是否取消,您的计时器只是要求cancel
该操作。
通过搜索在互联网上,我得到了一些人会想到有没有办法停止线程,没有任何一个知道吗?
不要打扰; 这是不是你停下来。 如果你有一个队列的引用,那么你可以调用dispatch_release
,它会在适当的时候被摧毁,但你不会与全局队列做到这一点。
杀死一个线程会杀了队列的池中的线程,并应被视为未定义行为一样好。
如果要控制线程的生命周期,创建你自己的线程,并与它的运行循环互动。 但确保您的程序在它们实现正常返回 - 不只是杀的东西,因为它不为你工作或不退还。 马丁·基R提及怎么会发生这种事 - 你的任务应该支持暂停,取消或其他手段来阻止自己在事件中的任务已经流氓。
北斗星的也提到了一个很好的中间地带。
使用的NSOperation和NSOperationQueue。
这是一个漫长的,但有益的指导。
http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues
在这种情况下,关键点对你来说,是有例如覆盖主要的。
@interface MyLengthyOperation: NSOperation
@end
@implementation MyLengthyOperation
- (void)main {
// a lengthy operation
@autoreleasepool {
for (int i = 0 ; i < 10000 ; i++) {
// is this operation cancelled?
if (self.isCancelled)
break;
NSLog(@"%f", sqrt(i));
}
}
}
@end
请注意,如果(self.isCancelled)在循环的中间。
这是管理的后台操作,而无需创建你自己的线程,并将它们直接管理的“现代”的iOS方式。