시스템 타이머는 90% CPU를 사용하여 무작위로 시작됩니다.

시스템 타이머는 90% CPU를 사용하여 무작위로 시작됩니다.

내 노트북은 ACPI 방전 이벤트를 안정적으로 보낼 수 없기 때문에 주기적으로 배터리 수준을 폴링하고 컴퓨터가 최대 절전 모드인지 결정하는 Systemd 타이머와 서비스를 만들었습니다. 그러나 시작 후 임의의 시간(보통 약 1시간) 동안 Systemd는 CPU의 약 90%를 사용하기 시작하고 systemctl stop타이머가 멈출 때까지 계속 사용합니다. 구체적으로 프로세스는 (CPU 사용량 기준)

~90%: /usr/lib/systemd/systemd --switched-root --system --deserialize 32
~80%: /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
~20%:/usr/lib/systemd/systemd-logind

타이머를 멈추면 이 모든 것이 거의 0으로 돌아갑니다. 관련 서류는 다음과 같습니다. 저는 Arch Linux, Systemd 버전 235.8-1을 실행하고 있습니다. hibernate-if-low-battery이 문제는 벽면 전원에 연결되어 있을 때에도 발생하고 심지어 실행 중이 아닐 때도 발생한다는 점은 주목할 가치가 있습니다 .

자동 취침 타이머

[Unit]
Description=Check battery level periodically and hibernate when low

[Timer]
OnBootSec=30s
OnUnitActiveSec=30s

[Install]
WantedBy=timers.target

자동 최대 절전 모드 서비스

[Unit]
Description=Check battery level and hibernate if low
ConditionACPower=false

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hibernate-if-low-battery

배터리가 부족하면 최대 절전 모드로 전환

#!/usr/bin/env bash

# Configuration.
BATTERY_PATH=/sys/class/power_supply/BAT0
CRITICAL_BATTERY_PERCENTAGE=5

# Calculate (the floor of) the battery percentage.
current_battery_level=$(< ${BATTERY_PATH}/energy_now)
max_battery_level=$(< ${BATTERY_PATH}/energy_full)
current_battery_percentage=$(((current_battery_level * 100)/max_battery_level))

if ((current_battery_percentage <= critical_battery_percentage)); then
    logger 'Hibernating due to low battery.'
    systemctl hibernate
fi

답변1

이는 타이머를 사용하여 ConditionACPower; 바라보다https://github.com/systemd/systemd/issues/5969. AC 전원 확인을 hibernate-if-low-battery스크립트로 이동하면 문제가 해결됩니다. 구체적으로 다음과 같이 작동합니다.

자동 최대 절전 모드 서비스

[Unit]
Description=Check battery level and hibernate if low

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hibernate-if-low-battery

배터리가 부족하면 최대 절전 모드로 전환

#!/usr/bin/env bash

# Configuration.
BATTERY_PATH=/sys/class/power_supply/BAT0
AC_PATH=/sys/class/power_supply/AC
CRITICAL_BATTERY_PERCENTAGE=5

# Get AC power status.
ac_power_active=$(< "${AC_PATH}/online")

# Calculate (the floor of) the battery percentage.
current_battery_level=$(< "${BATTERY_PATH}/energy_now")
max_battery_level=$(< "${BATTERY_PATH}/energy_full")
current_battery_percentage=$(((current_battery_level * 100)/max_battery_level))
battery_level_critical=$((current_battery_percentage <= critical_battery_percentage))

if (( ! ac_power_active && battery_level_critical )); then
    logger 'Hibernating due to low battery.'
    systemctl hibernate
fi

관련 정보