명령이 초당 평균 5번 실행되도록 하려면 어떻게 해야 합니까?

명령이 초당 평균 5번 실행되도록 하려면 어떻게 해야 합니까?

API 호출을 수행하고 결과로 데이터베이스를 업데이트하는 명령줄 스크립트가 있습니다.

API 공급자에서 초당 5개의 API 호출 제한을 설정했습니다. 스크립트를 실행하는 데 0.2초 이상이 걸립니다.

  • 명령을 순차적으로 실행하면 속도가 충분히 빠르지 않고 초당 1~2개의 API 호출만 수신됩니다.
  • 여러 터미널에서 동시에 명령을 순차적으로 실행하면 초당 5개 호출 제한을 초과할 수 있습니다.

명령줄 스크립트가 초당 거의 5번 실행되도록 스레딩을 조정하는 방법이 있습니까?

예를 들어, 프로그램은 5개 또는 10개의 스레드를 사용하여 실행되며, 이전 스레드가 200밀리초 이내에 스크립트를 실행한 경우 어떤 스레드도 스크립트를 실행하지 않습니다.

답변1

GNU 시스템에 있는 경우 pv다음을 수행할 수 있습니다.

cmd='
   that command | to execute &&
     as shell code'

yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh

동시에 최대 -P2020개까지 실행할 수 있습니다 .$cmd

-L10속도를 초당 10바이트 또는 초당 5줄로 제한합니다.

$cmds 속도가 느려지고 20개 제한에 도달하면 최소한 하나의 인스턴스가 반환될 xargs때까지 읽기가 중지됩니다 . 파이프에 대한 쓰기는 파이프가 가득 찰 때까지 동일한 속도로 계속됩니다(기본 파이프 크기가 ​​64KiB인 Linux에서는 거의 2시간이 소요됨).$cmdpv

그 시점에서는 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회입니다.

사용 ksh93(또는 명령이 소수 초를 지원 zsh하는 경우 사용 sleep):

typeset -F SECONDS=0
n=0; while true; do
  your-command &
  sleep "$((++n * 0.2 - SECONDS))"
done

그러나 동시성 수에는 제한이 없습니다 your-command.

답변2

간단히 말해서, 명령이 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

답변3

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;
}

스레드를 생성하는 방법을 알아보려면 다음을 사용하세요.스레드 만들기(이 코드를 붙여넣기 위해 사용한 링크입니다)

답변4

저는 Stéphane Chazelas의 pv솔루션을 한동안 사용해왔지만 일정 시간(몇 분에서 몇 시간 사이) 무작위로(그리고 자동으로) 종료되는 것을 발견했습니다. --편집: 이유는 최대 실행 시간을 초과하여 PHP 스크립트가 때때로 종료되고 상태 255로 종료되기 때문입니다.

그래서 간단하게 글을 쓰기로 했어요명령줄 도구이것이 바로 나에게 필요한 것입니다.

내 원래 목표를 달성하는 것은 간단했습니다.

./parallel.phar 5 20 ./my-command-line-script

이미 20개의 동시 프로세스가 있는 경우가 아니면 초당 거의 5개의 명령을 시작합니다. 이 경우 슬롯을 사용할 수 있을 때까지 다음 실행을 건너뜁니다.

이 도구는 상태 255 종료에 영향을 받지 않습니다.

관련 정보