privação de arquivos lockfile do Linux

2

Eu quero usar a funcionalidade lockfile para um script bash que será executado em paralelo. O problema é que, em uma funcionalidade como no script abaixo, uma inanição pode acontecer caso o primeiro a ser bloqueado seja chamado imediatamente novamente. Parece que lockfile está pesquisando com um tempo limite grande o suficiente para permitir que outros processos obtenham o bloqueio.

Isso é verdade? Como isso deve ser tratado?

lockfile test.lock
echo "TESTING $$"
sleep 10
rm test.lock

Por exemplo:

Duas conchas:
SH1, SH2 executam o script juntos,
SH1 adquire bloqueio, SH2 está bloqueado.
PROBLEMA:
Quando o SH1 é concluído e remove o bloqueio, o SH2 ainda está bloqueado (por cerca de um segundo ...) e, se o SH1 executar o script em um loop, o SH2 será bloqueado permanentemente.

    
por csny 19.01.2015 / 14:53

2 respostas

1

Você deve colocar o arquivo de trava em um tmpfs, porque cutucar arquivos de bloqueio irá impedi-lo de dormir.

Aqui estão duas soluções:

Sono Estático; Suficiente por alguns processos

WAIT=5  # max seconds between two procs; larger is nicer for the system
lockfile -${WAIT} -r-1 "${LOCKFILE}"

## payload

rm -f "${LOCKFILE}"
# sleep outside the lock for at least $WAIT seconds
#  to give another proc a chance to lock it
sleep ${WAIT}s

Sono Aleatório; Lida com muitos Procs, mas não Super Nice

MAX=5
MIN=3
WAIT=$((MIN+RANDOM/(1+MAX-MIN))) # random sleep between min and max
lockfile -${WAIT} -r-1 "${LOCKFILE}"

## payload

rm -f "${LOCKFILE}"
# sleep outside the lock for at least $WAIT seconds
#  to give another proc a chance to lock it
sleep ${WAIT}s

Os garçons mais longos se tornam mais agressivos; Nice para muitos Procs

MAX=600
MIN=1
WAIT=${MAX}  # max seconds between two procs; larger is nicer
while ! lockfile -r0 "${LOCKFILE}"
do
    sleep ${WAIT}s
    WAIT=$(( WAIT / 2 )) # backoff formula
    if [ ${WAIT} -lt ${MIN} ]; then
        WAIT=${MIN}
    fi
done

## payload

rm -f "${LOCKFILE}"
# reduced WAIT means likely to run again; alternatively use MAX
sleep ${WAIT}s
    
por 23.03.2016 / 11:25
0

Não tenho certeza se há algum problema.

O código do kernel para fs / locks.c contém o seguinte comentário:

 519 /* Insert waiter into blocker's block list.
 520  * We use a circular list so that processes can be easily woken up in
 521  * the order they blocked. The documentation doesn't require this but
 522  * it seems like the reasonable thing to do.
 523  */

Se você ainda não confia nisto, a única alternativa razoável é usar semáforos, semop (2), semget (2) .

    
por 19.01.2015 / 19:53