システムタイマーは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

タイマーを停止すると、すべてがほぼゼロに戻ります。関連書類は次のとおりです。私は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

関連情報