Вы можете использовать отображение памяти, чтобы «обмануть», создав ограниченную карту памяти над файлом, ограниченную начальным размером файла. Отдельно откройте другой дескриптор этого файла и найдите этот дескриптор до конца. Начните итерацию по карте памяти, записывая каждую считываемую строку в другой дескриптор файла, расположенный в конце файла. Типичный python
код
import mmap
with open('file', 'r+') as f1, open('file', 'r+b') as f2:
mm = mmap.mmap(f2.fileno(), 0) #memory map restricted to current file length
f1.seek(0, 2) #seek to end of file
for line in mm:
f1.write(line.replace('i', 'o', 1))
Вы столкнулись с двумя проблемами.
Это
(seq 200; sleep 20) | parallel -j10 -k echo
печатает:
1
2
, а затем останавливается, пока sleep 20
не будет выполнено.
Частичное исправление, по-видимому, заключается в перемещении start_more_jobs()
за пределы цикла while
:
--- a/src/parallel
+++ b/src/parallel
@@ -4062,9 +4062,8 @@ sub reaper {
# $stiff = pid of dead process
if(wantarray) {
push(@pids_reaped,$stiff);
- } else {
- $children_reaped++;
}
+ $children_reaped++;
if($Global::sshmaster{$stiff}) {
# This is one of the ssh -M: ignore
next;
@@ -4112,12 +4111,12 @@ sub reaper {
}
}
$job->cleanup();
- start_more_jobs();
if($opt::progress) {
my %progress = progress();
::status_no_nl("\r",$progress{'status'});
}
}
+ if($children_reaped) { start_more_jobs(); }
$opt::sqlmaster and $Global::sql->run("COMMIT;");
debug("run", "done ");
return wantarray ? @pids_reaped : $children_reaped;
Это может снизить производительность, если у вас много краткосрочных заданий. Я не измерял сколько.
Другая часть проблемы связана с проектным решением в GNU Parallel.
Аргументы в GNU Parallel считываются с помощью оператора ромба (<> ). Перед продолжением читается полная строка. Чтение из (sleep 20)
генерирует конец -файла -только после завершения sleep
и, таким образом, блокируется до завершения sleep
.
Таким образом, когда GNU Parallel читает последний байт, ему нужно дождаться завершения sleep
, чтобы обнаружить, что это действительно конец -файла -.
Я не вижу простого способа изменить эту часть дизайна.
К счастью, это не блокирует запуск заданий, как вы можете увидеть, запустив date
. Задания запускаются немедленно, это просто вывод, ожидающийsleep
:
(seq 20; sleep 5) | parallel -j10 -k 'date;echo'
Другими словами :Ваша проблема не связана с -N2
. Вы не можете видеть проблему здесь:
(printf '%s\0' {1..4}; sleep 2) | parallel --null -k --lb -N 2 echo {1} {2}
Но вы можете увидеть здесь проблему. Это делает паузу перед последними 4 -8 элементами:
(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 echo {1} {2}
Пауза перед последними 8 -10 элементами:
(printf '%s\0' {1..40}; sleep 2) | parallel -j8 --null -k --lb -N 2 echo {1} {2}
Запустив date
, вы увидите, что проблема не в запуске заданий -, а только в отсрочке печати:
(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 'date;'echo {1} {2}