CPU 부하가 가장 높은 프로세스를 자동으로 종료하는 방법은 무엇입니까?

CPU 부하가 가장 높은 프로세스를 자동으로 종료하는 방법은 무엇입니까?

때때로 프로그램이 백그라운드에서 잠겨 CPU 사용량이 높아지는 경우가 있습니다. 현재 가장 높은 CPU 부하를 유발하는 프로세스를 프로그래밍 방식으로 확인하고 종료할 수 있는 방법이 있습니까?

답변1

이러한 유형의 작업에 적합하다는 것을 안다면 더 나은 서비스를 제공할 수 있는 일련의 Unix 명령이 있습니다.

  • 정규식
  • 삭제
  • 그들 모두를 죽일

특히 오작동하는 프로세스의 이름을 알고 있는 경우 이러한 도구를 사용하여 "공격"을 더욱 표적화할 수 있습니다.

그들 모두를 죽일

Chrome을 종료하여 결국 해결해야 하는 문제가 계속 발생합니다. 나는 보통 그들을 모두 죽이기 위해 이 명령을 사용합니다.

$ killall chrome

pgrep 및 pkill

하지만 이렇게 할 수도 있으며 최신 프로세스만 처리할 수도 있습니다.

# to list
$ pgrep -n chrome
23108

# to kill
$ pkill -n chrome

명령줄을 기반으로 죽이기

-f실행 파일 이름뿐만 아니라 일치시키려는 긴 경로 매개 변수가 있는 프로세스에 액세스하기 위해 스위치를 추가할 수도 있습니다 .

예를 들어 다음과 같은 프로세스가 있다고 가정해 보겠습니다.

$ ps -eaf | grep some
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  8 22:54 pts/44   00:00:00 some weird command's friend

그들은 단지 Bash 쉘일 뿐입니다.ARGV0다음 이름으로 설정하세요. 그건 그렇고, 나는 다음 프로세스에 이 트릭을 사용했습니다.

$ (exec -a "some weird command name's friend" bash)

친구를 쫓아다니다

하지만 이러한 사람들이 많이 있고 명령줄에 "친구"가 있기 때문에 이들 중 특정 집합만 추적하고 싶다고 가정해 보겠습니다. 나는 이것을 할 수 있다:

$ pgrep -f friend
26673
26911

막내친구를 구해요

여러 개가 있고 최신 항목을 선택하려면 -n스위치를 믹스에 다시 추가하세요.

$ pgrep -fn friend
26911

-f스위치를 등록할 때 정규식을 사용할 수도 있으므로 다음과 같이 작동합니다.

$ pgrep -f "weird.*friend"
26673
26911

이름을 보여줘

스위치를 사용하여 프로세스 이름을 다시 확인할 수 있습니다 -l.

$ pgrep -f "weird.*friend" -l
26673 some weird command's friend
26911 some weird command's friend

제어 출력

또는 pgrep쉼표( ) ,로 구분된 프로세스 ID를 나열하도록 지시합니다.

$ pgrep -f "weird.*friend" -d,
26673,26911

다음과 같은 멋진 일을 할 수 있습니다.

$ ps -fp $(pgrep -f weird -d,)
UID        PID  PPID  C STIME TTY          TIME CMD
saml     26624 26575  0 22:51 pts/44   00:00:00 some weird command
saml     26673 26624  0 22:51 pts/44   00:00:00 some weird command's friend
saml     26911 26673  0 22:54 pts/44   00:00:00 some weird command's friend

그렇다면 높은 CPU 프로세스를 종료하는 방법은 무엇입니까?

나는 위의 내용을 사용하여 높은 CPU 프로세스를 보다 선택적으로 추구할 것입니다. 다음을 사용하여 죽일 수 있습니다:

# newest guys
$ pkill -nf vlc ; pkill -nf opensnap

# kill all of these
$ killall vlc; killall opensnap

CPU 로드를 살펴보세요.

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | grep -v grep
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     
26673  0.1  112m 106m 6392  848 5020 1504    0    0 S  20   0  0.0 some weird command's friend 

여기서 ,구분 기호를 쉼표( )로 변경했습니다. 이 스위치는 -d,파이프( |)라고도 합니다. 이 스위치를 -d\|사용하면 grep다음과 같이 프로세스 ID가 반환됩니다.

$ pgrep -f "weird.*friend" -d\|
26673|26911

grep -E ...그런 다음 특정 프로세스 ID를 기반으로 출력을 필터링 할 수 있도록 명령에 삽입합니다 .top

이는 큰 진전처럼 보일 수 있지만 이제 우리가 사용하는 프로세스 ID는 "weird.*friend"라는 특정 프로세스와 연관된 프로세스 ID일 뿐이라는 것을 확실히 알 수 있습니다.

여기에서 CPU가 가장 높은 프로세스를 찾아 정말로 원할 경우 종료할 수 있습니다.

높은 CPU 처리에 대한 보다 목표화된 접근 방식

$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | \
    grep -v grep | sort -nk14,14 | tail -1
26911  0.1  112m 106m 6408  848 4900 1512    0    0 S  20   0  0.0 some weird command's friend                                     

top위에 표시된 출력은 CPU 열(열 14)을 기준으로 정렬된 출력입니다. 가장 낮은 것부터 높은 것까지 정렬되므로 tail -1"weird.*friend" 프로세스 중에서 가장 높은 CPU가 될 마지막 행( )을 선택합니다.

답변2

이를 위해 "and" 프로그램 Auto-Nice Daemon을 설정할 수 있습니다.

몇 가지 알려진 문제 요인 목록과 세 가지 재처리 수준(점점 더 가혹하게 재처리할 수 있도록)을 설정했지만 그 중 하나라도 프로세스를 종료할 수 있었지만 이는 일반적으로 최후의 수단으로 예약되어 있습니다.

원하는 특정 CPU 로드 수준을 달성하기 위해 조정하는 것이 항상 쉬운 것은 아니지만, 도움이 될 수 있는(그리고 공격을 방지하여 문제가 되는 프로세스를 종료하는 것을 방지하는 데 도움이 되는) cpulimit와 같이 Nice 및 ionice로 프로그램을 시작한 다른 도구가 있습니다.

답변3

스크립트 편집

@msw, @sim 및 기타 사용자는 내 스크립트 개념에 대해 정당한 우려를 제기했습니다. @sim의 답변과 msw의 의견에 영감을 받아 앉아서 특정 문제(가끔 문제를 일으키는 여러 알려진 프로세스)를 해결하는 방법을 다시 생각해 보았습니다. 이것이 내가 생각해낸 것입니다:

#!/bin/bash

# tries to kill process with highest CPU load
# (if it is part of a specified list of troublemakers)

TROUBLEMAKERS="vlc opensnap glxgears stress"


sleep 1 # wait a few seconds (just as a precaution)

TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')

if [[ "$TROUBLEMAKERS" == *"$TOPNAME"* ]]
  then
      echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
      echo "In troublemaker list. Killing..."
      kill -9 $TOPPID
  else
      echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
      echo "Not in troublemaker list. Exiting..."
      exit 1
fi

exit 0

이전 스크립트와 달리 이 스크립트는 이름이 알려진 많은 문제 발생자(시스템을 잠그기 쉬운 프로세스) 중 하나와 일치하는 경우 CPU 로드가 가장 높은 프로세스만 종료합니다.


원본 스크립트

다음은 시스템에서 가장 높은 순간 CPU 로드를 유발하는 프로세스를 식별하고 이를 종료하는 간단한 스크립트입니다(GUI를 충돌시키는 Xorg 제외).

#!/bin/bash

# tries to kill process with highest CPU load
# (if it isn't Xorg)

sleep 1 # wait a few seconds (just as a precaution)

TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')

if [ "$TOPNAME" != "Xorg" ]
  then
      kill -9 $TOPPID
  else
      echo "CPU load caused by Xorg. Exiting."
      exit 1
fi

exit 0

TOPPROCESS스니펫은 다음을 기반으로 합니다.이 항목commandlinefu.com에서.

답변4

#!/bin/bash
pid=$(ps -eo %cpu,pid --sort -%cpu | head -n 2 | awk '{print $1 " " $2}')
if [[ -n $pid ]]; then
    kcpu=$(echo $pid | awk '{print $3}')
    kpid=$(echo $pid | awk '{print $4}')
    ift=$(echo "90"'<'$kcpu | bc -l)
    if [ $ift -eq "0" ]; then
        echo "kpid = $kpid"
        kill $kpid
    fi
else
echo "Does not exist"
fi

관련 정보