ActiveState
複数のシステムサービスを表示するGUIがあります。
10Hzでは、sd-bus APIを使用して、次のように各サービスを照会します。
sd_bus* bus;
sd_bus_error err = SD_BUS_ERROR_NULL;
char* msg = 0;
sd_bus_default_system(&bus);
sd_bus_get_property_string(bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1/unit/foo_2eservice",
"org.freedesktop.systemd1.Unit",
"ActiveState",
&err,
&msg);
私の問題は、このコードを実行しても/sbin/init
CPU/lib/systemd/systemd-logind
の約50%を消費することです。コードを分析すると、sd_bus_get_property_string
この関数の呼び出し数を減らす必要があることがわかります。
d-busインターフェイスを見るのは興味深いです。
busctl introspect \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/foo_2eservice \
org.freedesktop.system1.Unit
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Kill method si - -
.Ref method - - -
.Reload method s o -
.ReloadOrRestart method s o -
.ReloadOrTryRestart method s o -
.ResetFailed method - - -
.Restart method s o -
.SetProperties method ba(sv) - -
.Start method s o -
.Stop method s o -
.TryRestart method s o -
.Unref method - - -
.ActiveEnterTimestamp property t 0 emits-change
.ActiveEnterTimestampMonotonic property t 0 emits-change
.ActiveExitTimestamp property t 0 emits-change
.ActiveExitTimestampMonotonic property t 0 emits-change
.ActiveState property s "inactive" emits-change
...
これはActiveStateプロパティを伝えます。問題の変更。
ファイル記述子をどのように取得するか、その変更を受け取るためにイベントループに入りますか?
これD-バス仕様org.freedesktop.DBus.Properties.PropertiesChanged
属性が変更されると、systemdが信号を生成することを示します。シグナルを購読する方法を調べる必要があると思います。
ベストアンサー1
コメントを追加できないため、@ Stewartの回答を拡張しています。信号をイネーブルにするには、次の手順を実行する必要があります。申請彼らに:
Subscribe() はほとんどのバス信号を送信できます。信号に興味があるクライアントはこのメソッドを呼び出す必要があります。シグナルは、1つ以上のクライアントがこのメソッドを呼び出すときにのみ放出されます。
sd_bus_wait
なぜ戻ってこなかったのか気になるなら、次のような内容を見逃しているのです。
sd_bus_call_method(bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"Subscribe",
&error,
NULL,
NULL);