Bash 名前付きパイプ - 原子を読む

Bash 名前付きパイプ - 原子を読む

名前付きパイプに書き込むスクリプトを1つ設定し、名前付きパイプから読み込むスクリプトを4つ設定しました。

ほとんどの項目に問題はありませんが、入力行の処理がほとんど行われない場合、一部の読み取りは互いに競合し始め、結果のテキストは最大4行の処理の任意の文字の組み合わせです。

xargsまたは並列処理を使用できないのは、データベースへの接続に1秒かかるためです。これは通常、処理に最大1300行を追加します。

出力例:

MAIN.MK37のRunstatsが1秒で完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

MAIN.MKAPのRunstatsが0秒以内に完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

MAIN.MKALのRunstatsが0秒以内に完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

MAIN.MK49のRunstatsが0秒以内に完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

0秒後、AI.K1MAINの統計の実行に失敗しました。 SQL2306N表または索引「AI.K1MAIN」が存在しません。

MNM5では、Runstatが失敗します。 0以降:SQL0104N予期しないタグ「MNM5」。 「TBLE」の後に発見されました。予想タグには「」を含めることができます。 SQLステータス=42601

MAIN.MK50のRunstatsが0秒以内に完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

MAIN.MK52のRunstatsが0秒以内に完了しました:DB20000I RUNSTATSコマンドは正常に完了しました。

作家:

# Open pipe for writing
exec 10>"${PIPE_LOCATION}"

# Feed data
while read LINE; do
    echo "${LINE}" >&10
done <<< "${LIST}"

# Tell threads to stop
i=0
while [ "${i}" -lt 4 ]; do
    echo "stop" >&10
    (( i += 1 ))
done

# Close pipe
exec 10>&-

リーダー:

# Open Pipe
exec 10<"${PIPE_LOCATION}"

while read -u 10 -r SCHEMA TABLE; do
    if [[ "${SCHEMA}" == 'stop' ]]; then
        break
    fi

    #
    # Runstats Code Here
    #

done

# Close Pipe
exec 10<&-

読みを原子的にする方法はありますか?

私はサーバーのようにメインスレッドを調整し、入力が必要なときはいつでも4人の読者に要求を送信させることができると思います。これで問題を解決できます(それでも1本ではなく5本のパイプ!)。より簡単な解決策を提案できます。私は皆耳を傾けています!

ベストアンサー1

@MarkPlotnickの考えが正しいです。行を空白で埋め、固定サイズのレコードを使用して読み取るためにスクリプトを変更しました。

注:@Hauke Lagingが発見したように、ファイル記述子は10ではなく5です。

今、私は次のようにデータを提供しています。

# Feed data
while read LINE; do
    printf "%64s" "${LINE}" >&5
done <<< "${LIST}"

次のように読んでください。

while read -u 5 -N 64 -r LINE; do
    LINE=(${LINE})
    SCHEMA=${LINE[0]}
    TABLE=${LINE[1]}

そしてもうエラーはありません!

おすすめ記事