RaspberryPi[64] systemdのType=notifyでサービス間の起動順を正確に制御する方法
経緯
Raspberry Piで複数のsystemdサービスを連携させるとき、「起動順が合わず共有メモリが読めない」というトラブルはよくあります。私の環境でも esp32-com が xing_alart より先に動き出してしまい、sleep を入れて時間稼ぎしていました。
しかしこの方法だと再起動のタイミング次第で再発します。今回はその根本を systemdのType=notify と sd_notify() を使って解決した方法を紹介します。
問題点
作成側(xing_alart)が初期化完了を systemd に通知する。
待ち側(esp32-com)はその通知を受けてから起動する。
これを実現するのが、systemdのType=notifyとlibsystemdのsd_notify("READY=1") です。
手順
ライブラリの導入
sudo apt-get update
sudo apt-get install -y libsystemd-dev pkg-config
コード変更(先に動く側 共有メモリを作成する側)
共有メモリの初期化と shared_id.txt の書き出しが終わった直後に追加:
#include <systemd/sd-daemon.h>
sd_notify(0, "READY=1"); // 起動完了を通知
sd_notify(0, "STATUS=Running"); // 任意:状態表示用
ビルド
-lsystemd を追加
systemd設定例
先に起動する側
[Unit]
Description=XING alert service
After=local-fs.target
[Service]
Type=notify
ExecStart=/home/pi/work/XING/xing_alart -d 1
Restart=always
[Install]
WantedBy=multi-user.target
あとに起動する側
[Unit]
Description=ESP32 communication service
Requires=xing_alart.service
After=xing_alart.service
[Service]
ExecStart=/home/pi/work/XING/esp32-com -d 1
Restart=always
[Install]
WantedBy=multi-user.target

