我正在尝试使用flex来缓冲不断填充和重新填充的缓冲区。
我有多个线程使用自己独立的缓冲区副本。
在psuedo中,它在我的主程序中看起来像这样:
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声明相关联?
由于
答案 0 :(得分:2)
问题是flex的默认扫描程序不是可重入的 - 它在全局变量中存储了一堆信息(包括要读取的当前缓冲区),所以如果你试图让多个线程同时扫描东西,它们会我会一个接一个地走。
您需要使用%option reentrant
创建可重入扫描程序,然后为每个要使用的线程创建单独的yyscan_t
,使用yylex_init
进行初始化,然后作为额外参数传递适用于yylex
和yy_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);
}