3

いっぱいになって補充され続けるバッファに対してフレックスを使用しようとしています。

バッファの独自の独立したコピーで動作する複数のスレッドがあります。

疑似的には、私のメインプログラムでは次のようになります。

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 内で行い、それをメイン プログラムの 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 に答える