로드는 매우기만적인 숫자입니다. 소금 한알과 함께 섭취하십시오.
매우 빠르게 연속적으로 많은 작업을 생성하여 매우 빠르게 완료되는 경우 실행 큐의 프로세스 수가 너무 작아서로드를 등록 할 수 없습니다 (커널 수는 5 초마다 한 번씩로드).
8 개의 논리 코어가있는 호스트 에서이 예제를 고려하면이 파이썬 스크립트는 많은 CPU 사용량을 최고 (약 85 %)로 등록하지만 거의로드하지 않습니다.
import os, sys
while True:
for j in range(8):
parent = os.fork()
if not parent:
n = 0
for i in range(10000):
n += 1
sys.exit(0)
for j in range(8):
os.wait()
다른 구현으로, 이것은 wait
8 그룹으로 피 합니다 (테스트를 왜곡시킵니다). 여기서 부모는 항상 자식 수를 활성 CPU 수로 유지하려고 시도하므로 첫 번째 방법보다 훨씬 더 바쁘고 더 정확할 것입니다.
/* Compile with flags -O0 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define ITERATIONS 50000
int maxchild = 0;
volatile int numspawned = 0;
void childhandle(
int signal)
{
int stat;
/* Handle all exited children, until none are left to handle */
while (waitpid(-1, &stat, WNOHANG) > 0) {
numspawned--;
}
}
/* Stupid task for our children to do */
void do_task(
void)
{
int i,j;
for (i=0; i < ITERATIONS; i++)
j++;
exit(0);
}
int main() {
pid_t pid;
struct sigaction act;
sigset_t sigs, old;
maxchild = sysconf(_SC_NPROCESSORS_ONLN);
/* Setup child handler */
memset(&act, 0, sizeof(act));
act.sa_handler = childhandle;
if (sigaction(SIGCHLD, &act, NULL) < 0)
err(EXIT_FAILURE, "sigaction");
/* Defer the sigchild signal */
sigemptyset(&sigs);
sigaddset(&sigs, SIGCHLD);
if (sigprocmask(SIG_BLOCK, &sigs, &old) < 0)
err(EXIT_FAILURE, "sigprocmask");
/* Create processes, where our maxchild value is not met */
while (1) {
while (numspawned < maxchild) {
pid = fork();
if (pid < 0)
err(EXIT_FAILURE, "fork");
else if (pid == 0) /* child process */
do_task();
else /* parent */
numspawned++;
}
/* Atomically unblocks signal, handler then picks it up, reblocks on finish */
if (sigsuspend(&old) < 0 && errno != EINTR)
err(EXIT_FAILURE, "sigsuspend");
}
}
이 동작의 이유는 알고리즘이 실제 작업을 실행하는 것 (10000까지 계산)보다 자식 프로세스를 만드는 데 더 많은 시간을 소비하기 때문입니다. 아직 생성되지 않은 작업은 '실행 가능'상태로 계산할 수 없지만 생성 된 CPU 시간에 % sys를 차지합니다.
따라서 어떤 작업을 수행하든 많은 수의 작업이 빠르게 연속적으로 생성됩니다 (스레드 또는 프로세스).