참고 사항

참고 사항

Linux는 (아직) POSIX.1 표준을 따르지 않습니다.설명하다프로세스의 a는 renice"프로세스의 모든 시스템 전체 스레드"에 영향을 미칩니다.pthreads(7) 문서"스레드는 공통의 좋은 가치를 공유하지 않습니다".

그러나 때로는 renice특정 프로세스와 관련된 "모든 것"을 갖는 것이 편리할 수 있습니다(예: Apache 하위 프로세스 및 해당 스레드 모두). 그래서,

  • renice어떻게 다 얻을 수 있어?특정 프로세스에 속합니까?
  • renice어떻게 다 얻을 수 있어?하위 프로세스특정 프로세스에 속합니까?

나는 매우 간단한 해결책을 찾고 있습니다.

알아요프로세스 그룹때로는 도움이 될 수도 있지만 내가 원하는 작업에 항상 맞는 것은 아닙니다. 더 광범위하거나 다른 프로세스 집합을 포함할 수 있습니다.

cgroup관리자를 사용하는 systemd것도 도움이 될 수 있지만, 그것에 대해 듣고 싶더라도 주로 "표준" 솔루션을 찾고 있습니다.

편집: 또한 man (7) pthreads"프로세스의 모든 스레드는 동일한 스레드 그룹에 배치됩니다. 스레드 그룹의 모든 구성원은 동일한 PID를 공유합니다"라고 표시됩니다. 그렇다면 renice자체 PID 없이 무언가를 가질 수 있습니까?

답변1

/proc/$PID/task특정 프로세스의 모든 스레드를 찾는 데 사용할 수 있으므로 다음을 사용할 수 있습니다.

$ ls /proc/$PID/task | xargs renice $PRIO

모든renice특정 프로세스에 속합니다.

동일한 방법을 /proc/$PID/task/$PID/children사용하여 모든 항목을 찾을 수 있습니다.하위 프로세스(또는 /proc/$PID/task/*/children모두 원한다면하위 프로세스모두주어진 프로세스).

$ cat /proc/$PID/task/$PID/children | xargs renice $PRIO
$ cat /proc/$PID/task/*/children | xargs renice $PRIO

답변2

모든 PID 찾기renice 재귀적으로

보류 중인 프로세스의 하위 프로세스(하위 프로세스 또는 스레드 그룹의 프로세스)인 모든 프로세스("일반" 또는 "스레드")의 PID를 가져와야 합니다. 이는 재귀적이어야 합니다(자식의 자녀를 고려).

안톤 레온티예프대답은 이를 수행하기 위한 힌트를 제공합니다. 폴더에 있는 모든 폴더 이름은 잠재적인 하위 프로세스를 나열하는 파일이 /proc/$PID/task/포함된 스레드의 PID입니다 .children

그러나 재귀 기능이 부족하므로 이를 찾는 빠르고 더러운 쉘 스크립트는 다음과 같습니다.

#!/bin/sh
[ "$#" -eq 1 -a -d "/proc/$1/task" ] || exit 1

PID_LIST=
findpids() {
        for pid in /proc/$1/task/* ; do
                pid="$(basename "$pid")"
                PID_LIST="$PID_LIST$pid "
                for cpid in $(cat /proc/$1/task/$pid/children) ; do
                        findpids $cpid
                done
        done
}

findpids $1
echo $PID_LIST

프로세스 PID 1234가 재귀적으로 처리하려는 프로세스인 경우 이제 다음을 수행할 수 있습니다.

renice -n 15 -p $(/path/to/findchildren.sh 1234)

참고 사항

가치와 CPU 점유율 중 어느 것이 더 좋습니까?

이제 자동 작업 그룹화로 인해 특히 다음을 사용할 때 주의하세요.체계. 보다이 답변자세한 내용은.

스레드와 프로세스의 차이점

노트:이 답변Linux 스레드가 정확하게 설명되었습니다.

간단히 말해서, 커널은 "실행 가능한 엔터티"만 처리합니다.달리기그리고예정됨. 커널 관점에서는 이러한 엔터티를 프로세스라고 합니다. 스레드는 (적어도) 메모리 공간과 신호 처리기를 다른 프로세스와 공유하는 프로세스일 뿐입니다. 이러한 각 프로세스에는 시스템 전반에 걸친 고유 식별자인 PID(프로세스 ID)가 있습니다.

그 결과, 당신은할 수 있는 renice각 "스레드"는 고유한 특성을 갖고 있으므로 분리되어 있습니다.내 자신의PID 1 .


1 본다이 답변PID(ProcessID)와 TID(ThreadID)의 차이점에 대해 자세히 알아보세요.

답변3

때때로 TID 또는 ps 명령 LPW로 작성되는 프로세스 PID와 스레드 ID를 혼동해서는 안 됩니다. 이 s명령에는 스레드를 표시하는 옵션이 있으며 아래 top또는 아래 htop스레드 사이를 전환 하고 H문자별로 진행할 수 있습니다. @Totor가 이전에 말했듯이 NPTL(현재 커널 > 2.6 구현)을 사용하면 모든 스레드의 pid는 동일하지만 tid는 다릅니다. 다음을 사용하여 프로세스의 모든 스레드를 표시할 수 있습니다.

$ ps -Ljf <pid>

이러한 tid는 기본 디렉토리의 이름입니다 /proc/<pid>/task.레니스(1)기본 인수가 pid라고 가정하면 pid에 적용하면 메인 스레드에 대해서만 조정됩니다(이것은 Linux 구현의 버그입니다.우선순위 설정(2)), 스레드의 tid 및 크기 조정에도 적용할 수 있습니다. 이것이 @Anton의 답변이 유효한 이유입니다.

그러나 대부분의 경우 원하는 결과를 얻는 더 쉬운 방법이 있습니다. 이러한 모든 스레드는 그룹 리더의 pid인 동일한 pgid를 공유합니다. pgid를 통해 다음 명령을 실행하여 다시 시작할 수 있습니다.

$ renice -g <pgid>

동일한 리더 세트에 의존하는 다른 프로세스를 다시 활성화하지 않으려면 @Anton의 레시피를 사용해야 합니다.

$ renice <priority> $(ls -1 /proc/<pid>/task)

또는:

$renice <priority> $(ps --no-header -Lo tid <pid>)

재사용하려는 프로세스, 즉 동일한 pgid를 공유하는 프로세스 외에 동일한 그룹에 다른 프로세스가 있는지 알고 싶을 수도 있습니다. 당신은 그것을 사용할 수 있습니다참고(1), ps그룹 리더별로 프로세스를 선택할 수는 없지만 grep을 통해 ps그렇게 할 수 있습니다. pgid를 사용한 프로세스는 다음 1908과 같이 제공됩니다.

$ ps --no-header axo pid,pgid |sed -n '/^ *[0-9][0-9]*  *1908/s/[0-9][0-9]* *$//p'

또는 sed보다 awk를 선호하는 경우:

$ ps --no-header axo pid,pgid|awk '{if ($2=="1908") print $1;}'

답변4

renice를 사용할 때 -p(프로세스 ID) 대신 -g(프로세스 그룹) 매개변수를 사용하는 것이 좋습니다. bash-foo 없이도 동일한 작업을 수행할 수 있습니다.

(sudo) renice -n <NEW_PRIORITY> -g <MAIN_PROCESS_ID>

관련 정보