我正在用 C++ 开发一种 AST 解释的脚本语言。解释器有一个简单的 stop-the-world 标记和清除垃圾收集器,每当触发收集时,它会向所有应用程序线程发送停止请求,然后等待所有线程暂停。每个线程只有一个可以接受gc请求的安全点,放置在一个方法exec()
中,每次执行一行解释代码时都会调用该方法,如下所示:
void Thread::exec(const Statement *stmt){
if(runtime->gcPauseRequested){
this->paused = true;
gcCallback.notify_one(); //notify GC that this thread is now waiting
gcConditionVariable.wait(gcLock); //wait for GC to be finished
this->paused = false;
}
// execute statement...
}
和垃圾收集器:
void MemoryManager::gc(){
runtime->gcPauseRequested = true;
while(!allThreadsArePaused()){
gcCallback.wait(gcCallbackLock);
}
runtime->gcPauseRequested = false;
//garbage collect and resume threads...
}
问题是:语言支持本地函数调用,但是在当前系统中,如果一个线程正在执行一个需要很长时间的本地调用(例如本地sleep
函数),所有其他应用程序线程和垃圾收集器线程将等待该线程到达安全点,以便可以执行垃圾收集。有没有办法避免这种情况?