我曾试图通过将我的一个项目变成一个多线程应用程序来加快它的速度。该项目是一个简单的编程语言。它有一个解析器和解释器。解析器解析文件,解释器解释解析器发送给它的标记。我把解析器和解释器移到了它们自己的线程中,以消除解析器给解释器一个令牌时的停机时间,解析器最终等待解释器完成操作,而不是继续解析。这样,解析器将是生产者,解释器将是消费者。我希望这将允许解析器在解释器解释解析器给出的标记时继续解析。虽然,在随机的时间,我会得到一个分割错误后,程序finsihes。有时解释器不能看到队列中的任何东西,或者只能得到队列中的部分内容。其他时候,它将运行相同的令牌两次。我不知道这里发生了什么,或者为什么。
下面是解析器中使用的相关代码:
void threadedParse(std::string fileName, BambooVM *fileVM)
{
// Queue that stores all of the tokens
std::queue<Token> queue;
std::thread thread(watch, std::ref(queue), fileVM);
/*
...
*/
while (std::getline(file, line)) {
// Push tokens to queue, read file, etc
}
/*
...
*/
// Wait for the queue to empty after parsing all tokens
while (!queue.empty())
continue;
thread.detach();
}
函数“watch”监视提供的队列并等待元素,当它找到一个元素时,它应该解释该元素并将其弹出队列。
void watch(std::queue<Token> &queue, BambooVM *vm)
{
Utils::debug("Starting interpreter...");
while (1)
{
if (!queue.empty())
{
interpret(queue.front(), vm);
queue.pop();
}
}
}
我做了什么来尝试解决这个问题:
- Used a blocking & non blocking SPSC queue
- 使用状态变量(
int *state
,1表示项目准备消费,0表示空)而不是queue.empty()
来尝试和控制何时消费令牌。
应该注意的事情:解析器有时可能比解释器运行得慢,解释器也可能比解析器运行得慢。我不希望解释器一直等待解析器,除非没有要解释的元素。解析器也应该永远不必等待任何事情,并且应该始终处于活动状态。
我是线程和多线程应用程序的新手,如果我的问题不清楚,我道歉。我试着把它说得尽可能清楚。
1条答案
按热度按时间fhg3lkii1#
您确实需要使用一些互斥锁,可能还需要一个条件变量。
虽然我是从自己的一些代码中剪切和粘贴的,但这并没有经过测试。