Bash Named Pipe - Leitura atômica

3

Eu configurei um script para escrever em um pipe nomeado e, em seguida, quatro scripts para ler o pipe nomeado.

Para a maioria das entradas, não há problemas, mas quando há pouco processamento a ser feito nas linhas de entrada, algumas das leituras começam a entrar em conflito umas com as outras e o texto resultante é uma combinação de caracteres aleatórios de (até) 4 linhas para os (até) 4 processos.

O motivo pelo qual não posso usar xargs ou paralelos é que, no tempo de conexão com o banco de dados, leva 1 segundo, o que resulta em uma média de aproximadamente 1300 linhas que precisam ser processadas.

Exemplo de saída:

Completed Runstats on MAIN.MK37 in 1s: DB20000I The RUNSTATS command completed successfully.

Completed Runstats on MAIN.MKAP in 0s: DB20000I The RUNSTATS command completed successfully.

Completed Runstats on MAIN.MKAL in 0s: DB20000I The RUNSTATS command completed successfully.

Completed Runstats on MAIN.MK49 in 0s: DB20000I The RUNSTATS command completed successfully.

Failed Runstats on AI.K1MAIN after 0s: SQL2306N The table or index "AI.K1MAIN" does not exist.

Failed Runstats on MNM5. after 0s: SQL0104N An unexpected token "MNM5." was found following "TBLE". Expected tokens may include: "". SQLSTATE=42601

Completed Runstats on MAIN.MK50 in 0s: DB20000I The RUNSTATS command completed successfully.

Completed Runstats on MAIN.MK52 in 0s: DB20000I The RUNSTATS command completed successfully.

Escritor:

# 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>&-

Leitor:

# 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<&-

Existe alguma maneira de tornar as leituras atômicas?

Eu estava pensando que poderia coordenar o thread principal como um servidor, e os quatro leitores poderiam enviar um pedido toda vez que ele quisesse alguma entrada, o que provavelmente resolveria o problema (5 pipes ao invés de 1!), mas se houver uma solução mais fácil que alguém possa sugerir, sou todo ouvidos!

    
por earthiverse 10.02.2015 / 19:47

1 resposta

2

@MarkPlotnick teve a ideia certa. Eu mudei o script para preencher a linha com espaços e fazer a leitura usar registros de tamanho fixo.

Nota: O descritor de arquivo agora é 5 em vez de 10, devido aos achados do @Hauke Laging

Agora eu alimentei os dados da seguinte forma:

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

E leia assim:

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

e não há mais erros!

    
por 10.02.2015 / 20:56

Tags