초당 평균 5 번씩 명령을 실행하는 방법은 무엇입니까? 스크립트가 있습니다. API 공급자와의 API 호출은 초당

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 종료에 민감하지 않습니다.