O motivo da falha pode ser encontrado em man 2 flock
:
Locks created by flock() are associated with an open file description (see open(2)). This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these descriptors.
Isso significa que, como todos os seus processos herdam o mesmo descritor de arquivo, quando um deles bloqueia, todos eles o compartilham. E bloquear o mesmo descritor de arquivo duas vezes é um não operacional.
Minha solução usual para coisas assim é bloquear o script em si (embora isso cause problemas se você executar o script várias vezes simultaneamente).
#!/bin/bash
fun()(
exec 3<"$0"
flock 3 || { echo >&2 "$BASHPID: FAIL: $?"; exit 1; }
echo "$BASHPID begin"
sleep 1;
echo "$BASHPID end"
)
fun &
fun &
fun &
fun &
fun &
fun &
fun &
fun &
fun &
wait