3

我正在尝试对不断填充和重新填充的缓冲区使用 flex 。

我有多个线程使用它们自己独立的缓冲区副本。

在我的主程序中,它看起来像这样:

while(forever)
{
-fill buffer buf-
buf[length+1] = '\0';
buf[length+2] = '\0';
yy_scan_bytes(&buf, length+2);
yylex();
}

其中多个线程正在运行该循环,并且都拥有它们的 buf 副本。

我的 lex 文件中有一条规则,如下所示:

<<EOF>> {yyterminate(); yy_delete_buffer(YY_CURRENT_BUFFER);}

试图在缓冲区运行后进行清理。

我不确定我这样做是否正确,因为这是我第一次尝试将 flex 扫描仪与另一个程序结合使用。在 flex 中进行所有缓冲区处理,并将其与主程序中的 extern 声明链接起来会更好吗?

谢谢

4

1 回答 1

3

问题是 flex 的默认扫描器不是可重入的——它将一堆信息(包括要读取的当前缓冲区)存储在全局变量中,所以如果你尝试让多个线程同时扫描东西,它们会遍地都是。

您需要使用%option reentrant创建一个可重入扫描器,然后yyscan_t为每个要使用的线程创建一个单独的扫描器,您使用它进行初始化,yylex_init然后将其作为额外参数传递给两者yylexyy_scan_bytes

此外,yyterminate扫描仪会立即返回,因此您yy_delete_buffer永远不会拨打电话。您需要在扫描仪返回后调用它:

yyscan_t local;
yylex_init(&local);
while(forever)
{
    -fill buffer buf-
    buf[length+1] = '\0';
    buf[length+2] = '\0';
    YY_BUUFER_STATE bs = yy_scan_bytes(&buf, length+2, local);
    yylex(local);
    yy_delete_buffer(bs, local);
}
于 2012-12-18T22:48:23.827 回答