API 호출을 수행하고 결과로 데이터베이스를 업데이트하는 명령 줄 스크립트가 있습니다.
API 공급자와의 API 호출은 초당 5 회로 제한됩니다. 스크립트를 실행하는 데 0.2 초 이상 걸립니다.
- 명령을 순차적으로 실행하면 명령이 충분히 빠르게 실행되지 않으며 초당 1 또는 2 개의 API 호출 만 수행합니다.
- 명령을 순차적으로 실행하지만 여러 터미널에서 동시에 실행하면 5 호출 / 초 제한을 초과 할 수 있습니다.
명령 줄 스크립트가 초당 거의 정확히 5 번 실행되도록 스레드를 조정하는 방법이 있습니까?
예를 들어, 5 개 또는 10 개의 스레드로 실행되며 이전 스레드가 200ms 미만 전에 실행 한 스레드는 스크립트를 실행하지 않습니다.
답변
GNU 시스템에서을 가지고 있다면 다음을 pv
수행 할 수 있습니다.
cmd='
that command | to execute &&
as shell code'
yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
은 -P20
대부분 20에서 실행하는 $cmd
동시에.
-L10
속도를 초당 10 바이트로 제한하므로 초당 5 행입니다.
귀하의 경우 $cmd
의 느린 두되고 도달 할 20 한계가 발생하고 xargs
한 때까지 읽기 중지됩니다 $cmd
적어도 반환의 인스턴스입니다. pv
파이프가 가득 찰 때까지 동일한 속도로 파이프에 계속 쓰기를 수행합니다 (기본 파이프 크기가 64KiB 인 Linux에서는 거의 2 시간이 걸립니다).
그 시점에서 pv
쓰기를 중지합니다. 그러나 그 후에도 xargs
읽기를 다시 시작할 때 pv
초당 평균 5 줄을 유지하기 위해 가능한 빨리 빨리 보내야하는 모든 줄을 잡아서 보내려고합니다.
즉, 20 개의 프로세스가 평균 요구 사항에서 초당 5 회 실행을 충족 할 수있는 한 가능합니다. 그러나 한계에 도달하면 새 프로세스가 시작되는 속도는 pv의 타이머가 아니라 이전 cmd 인스턴스가 리턴하는 속도에 의해 결정됩니다. 예를 들어, 20 개가 현재 실행 중이고 10 초 동안 있고 그 중 10 개가 동시에 모두 완료하기로 결정한 경우 한 번에 10 개의 새로운 항목이 시작됩니다.
예:
$ cmd='date +%T.%N; exec sleep 2'
$ yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
09:49:23.347013486
09:49:23.527446830
09:49:23.707591664
09:49:23.888182485
09:49:24.068257018
09:49:24.338570865
09:49:24.518963491
09:49:24.699206647
09:49:24.879722328
09:49:25.149988152
09:49:25.330095169
두 실행 사이의 지연이 항상 정확히 0.2 초가 아니더라도 평균적으로 초당 5 회입니다.
with ksh93
(또는 명령이 소수 초를 지원 하는 zsh
경우 sleep
) :
typeset -F SECONDS=0
n=0; while true; do
your-command &
sleep "$((++n * 0.2 - SECONDS))"
done
your-command
그러나 동시 수에는 제한이 없습니다 .
답변
간단히 말해, 명령이 1 초 미만 지속되면 초당 5 개의 명령을 시작할 수 있습니다. 분명히 이것은 매우 파열입니다.
while sleep 1
do for i in {1..5}
do mycmd &
done
done
명령이 1 초 이상 걸릴 수 있고 명령을 분산시키려는 경우 시도해 볼 수 있습니다
while :
do for i in {0..4}
do sleep .$((i*2))
mycmd &
done
sleep 1 &
wait
done
또는 최소 1 초로 독립적으로 실행되는 5 개의 개별 루프를 가질 수 있습니다.
for i in {1..5}
do while :
do sleep 1 &
mycmd &
wait
done &
sleep .2
done
답변
C 프로그램으로
예를 들어 0.2 초 동안 잠 들어있는 실을 사용할 수 있습니다
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t tid;
void* doSomeThing() {
While(1){
//execute my command
sleep(0.2)
}
}
int main(void)
{
int i = 0;
int err;
err = pthread_create(&(tid), NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
return 0;
}
스레드를 생성하는 방법을 알고 그것을 사용 : 스레드를 생성 (이이 코드를 붙여 사용했습니다 링크입니다)
답변
node.js 를 사용 하면 응답이 콜백 함수를 통해 이루어지기 때문에 응답 시간이 얼마나 걸리더라도 200 밀리 초마다 bash 스크립트를 실행 하는 단일 스레드 를 시작할 수 있습니다 .
var util = require('util')
exec = require('child_process').exec
setInterval(function(){
child = exec('fullpath to bash script',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
},200);
이 자바 스크립트는 200 밀리 초마다 실행되며 콜백 함수를 통해 응답을 function (error, stdout, stderr)
받습니다.
이러한 방식으로 명령 실행 속도 또는 응답 속도 또는 응답 대기 시간과 상관없이 초당 5 회 호출을 초과하지 않도록 제어 할 수 있습니다.
답변
나는 Stéphane Chazelas pv
기반 솔루션을 얼마 동안 사용했지만 몇 분에서 몇 시간까지 어느 시간이 지나면 무작위로 (그리고 조용히) 빠져 나왔다는 것을 알았습니다. – 편집 : 그 이유는 최대 실행 시간이 초과되어 내 상태가 255 인 PHP 스크립트가 때때로 종료 되었기 때문입니다.
그래서 필요한 것을 정확하게 수행 하는 간단한 명령 줄 도구 를 작성하기로 결정했습니다 .
내 원래 목표를 달성하는 것은 다음과 같이 간단합니다.
./parallel.phar 5 20 ./my-command-line-script
이미 20 개의 동시 프로세스가없는 경우 초당 정확히 5 개의 명령을 시작합니다.이 경우 슬롯이 사용 가능해질 때까지 다음 실행을 건너 뜁니다.
이 도구는 상태 255 종료에 민감하지 않습니다.