標準入力のバッファリング問題

将棋所で動く思考エンジンのサンプルプログラムにLesserkaiというのがある。将棋所の作者のページからダウンロード出来るので、USIプロトコル対応のプログラムを書く上で公式のサンプルプログラムだと言っても過言ではないのだが、ちょっと困った問題がある。

このLesserkaiのmain関数の冒頭で次のように標準入出力のバッファリングを無効にしている部分がある。

Visual C++の古いランタイムでは標準出力がリダイレクトされているときにflushを呼び出しても標準出力のバッファをすべて吐き出さないことがあったような気がしないでもないが(おそらく実装上のバグ)、いまやそんなことはないので、こんなことはする必要はない。

必要はないというか、Visual C++2015でこれをしてしまうと、iostreamを使った標準入力は、改行が二回来ないと入力されない気がする。詳しく調べていないので理由はよくわからないが、上のコードを書いては駄目だということは私はわかっている。

この件でうさ親さんがハマっていたようだ。他にもハマっている人がいるかと思うので記事にしておく。

Visual Studio 2015はexpress edition(or community edition)なら無償で使えるし、この無償の環境で十分将棋ソフトが開発できるので、お勧めしたいのだが、上のように2015にupdateしたら(自分の作っている)将棋ソフトが動かなくなったという事案がなくはない。本記事が、その解決の一助になれば幸いである。

あと、本件に関して、詳しいことがわかる人がいればコメントお願いします。

標準入力のバッファリング問題」への16件のフィードバック

  1. WCSC26で導入されるフィッシャールールについて御意見下さい。
    やねうら王も当然対応させますよね?(出場して欲しい直喩)

  2. Julia (私がハマっている言語)で自作エンジン作ろうと思って、USI でやりとりするところだけ作ろうとしているのですが、将棋所にエンジン登録しようとするとそのまま、登録中のまま、止まってしまうので、Electron将棋 などの他の GUI とかでも試していたのですが、うまく行かず、C とか C++ で書いたら正常に動き、Python で書くとうまく行かず、flush してないせいなのかとおもって、flush すると Python のやつは、Electron 将棋でうまくいき、将棋所ではうまく行かず、Julia のやつはどっちでもうまく行かず、困り果てています。どうも、Julia インタープリタ自体がエンジン登録しようとすると起動しないみたいなのですが、謎です。そして、将棋所では Python (flush 付き) のやつがうまく行かないのが、謎です。なにか、コンピュータ将棋界隈で知られていることはありませんか?

    Python のやつはこんな感じなんですけどねえ…

    #!/usr/bin/env python3
    while True:
    line = input()
    if line == “quit”:
    break
    elif line == “usi”:
    print(“id name PythonEngine”, flush=True)
    print(“id author Paalon”, flush=True)
    print(“usiok”, flush=True)

    • “usi”を受け付ける前にエンジン側は起動時に”id name …”~”usiok”を送ってしまってはどうでしょう?(“usi”は無視する)
      あとはPython版のdlshogiでも同様の現象になるかやってみるだとか。
      それと、input()で本当に何も来てないのかログに書き出して確認したいところですな。改行だけ送られてきているとかそういうパターンもありますし。
      あとそのコードはbash使ってるのだと思いますが、bashがバッファリングしているということはないでしょうか。(バージョンによるのか知りませんが)

      • そういえば、1行目1文字目の#!が通用するような環境にはstdbufとかいうコマンドがあったりして、わざわざsetvbufのようなものとかを書き足したりしなくてもそのあたりのバッファリングの有無の差の実験とかもできたような?

      • Electron 将棋 v1.3.0 のリリースされたものだと Julia で書いたやつを登録しようとすると、timeout になってエラーが出ますが、git clone して v1.3.0 の tag のやつを自分で npm run electron:serve したやつだとエラーが出ずに正常に登録されました。なぜそうなるのかはまだ分かりません。そして将棋所は登録しようとすると、クラッシュするのは相変わらずです。

          • Electron 将棋におけるこの問題の原因は解決しました。詳細は以下の通りです。
            https://github.com/sunfish-shogi/electron-shogi/issues/231#issuecomment-1279851724

            > macOS で Finder 上でクリックしたり、Spotlight から起動したアプリケーションの環境変数はデフォルトだと /usr/bin:/bin:/usr/sbin:/sbin となっていて、/usr/local/bin は入っておらず、
            >
            > sudo launchctl config user path /usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
            >
            > などとして設定(要再起動)しないと、いけない

            というわけで標準入力のバッファリング問題は関係なさそうです。

            将棋所では相変わらず動かないです・・・将棋所の作者さんに聞いてみます。

          • 将棋所で動かない問題、解決しました!将棋所は shebang とか関係なく、テキストファイルは全て Unix シェルのスクリプトとして解釈するみたいです。なので、例えば指定したいファイルが $ENGINE_PATH/engine としたら、$ENGINE_PATH/engine-for-shogidokoro$ENGINE_PATH/engine とでも書いて $ENGINE_PATH/engine-for-shogidokoro を登録すれば実行できる仕様なようです。へんてこりんですね。

コメントを残す

メールアドレスが公開されることはありません。