14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「デーモン化とは?」をコードと観察で整理してみた─TTY・SID・initとsystemd

Last updated at Posted at 2025-07-08

はじめに

Linux を使っているとよく出てくる「デーモン」という存在。
「そもそもデーモンって何?」「なぜそんな儀式めいたことをするの?」
そういった問いを、手元でデーモンを再現してみながら観察・まとめた記録です。

ちゃんと理解してるかどうかの確認も兼ね、観察ログや再現コードも含めて書き残しておきます。

デーモン を ひとこと で

バックグラウンドに常駐し、黙々と自分の責務を果たすべく孤児となったプロセスのこと。
生まれながらにデーモンだった者はいない ――
孤児となることで、初めて一人前のデーモンとなります。

デーモンにならなくても、 &nohup でバックグラウンドプロセスとして動かしておくだけではだめ?

&nohup では TTY やセッションとの結びつきが残るため、完全に自律したサービスとは言えません。

「init や systemd に管理してほしい」「ログを一元化したい」「再起動も任せたい」「ほかのサービスと連携したい」といった目的のためには、デーモン化する必要があります。

ただし、デーモンになっただけでは init や systemd にサービスとして自動的に “管理” されるわけではありません。

init 時代には、デーモン化したプロセスを PID ファイルなどで明示的に管理対象とする必要がありました。

一方、systemd では、サービス用の unit ファイルを用意しておくことで、起動・停止・監視まで一貫して任せることができます。

なぜ デーモン は孤児となる必要があるのか?

孤児になったプロセスは、カーネルにより、PID 1 のプロセス(init や systemd)が親となり引き取ってくれるためです。

親(プロセス)は子のために自ら命を絶つ。
孤児となることで、誰からも干渉されず独立して動けるようになります (= 以下が可能となる)

  • TTY(端末)やユーザーセッションとの切り離し
  • ログインユーザーがログアウトしても終了しない(セッション切断耐性)

TTY とは?

TTY(テレタイプ端末)とは、もともと物理的な端末装置(キーボード + プリンタのような機械)に由来する、文字情報の入出力を行う装置のことです。

現代の Linux では、その流れを引き継いで、ターミナルとの接続を表すデバイスファイル(例: /dev/pts/0 など)が「TTY」と呼ばれます。
プロセスは、自分にひもづけられた TTY を通じてキーボード入力を受け取り、画面出力を行います。

セッションリーダー とは?

自らセッションを開始し(setsid())、そのセッションの代表となったプロセスのことです。
また、TTY が切断されたときに送られる SIGHUP(Hang Up シグナル)を受け取るのもセッションリーダーです。

SID が同じプロセスは同じセッション。

bash 自身の PID = SID ← 自分でセッションを開始してるプロセスがセッションリーダー。
セッションリーダーを起点にプロセスグループが構成される。

手元のターミナルで PID や SID を観察してみる

PID と SID が一致しているため、この bash は自らセッションを開始した「セッションリーダー」

$ ps -o pid,ppid,sid,pgid,tty,cmd

PID    PPID     SID    PGID TT       CMD
114587  114581  114587  114587 pts/1    bash
167542  114587  114587  167542 pts/1    ps -o pid,ppid,sid,pgid,tty,cmd

デーモンのお作法

python による "もどき" 作成例

デーモン化には、親を殺し、セッションを抜け、入出力を閉じ……といった一連の“儀式”があります。
かつては各サービスがそれを自前で書いていた時代もありました。
ここでは、その流れを Python で再現してみます。

import os
import time

def log(msg):
    with open("/logs/fork_test.log", "a") as f:
        f.write(f"{msg}\n")

try:
    tty = os.ttyname(0)
except OSError:
    tty = 'no tty'

# 生まれたてのプロセス
log(f"[start] pid={os.getpid()} ppid={os.getppid()} sid={os.getsid(0)} pgid={os.getpgrp()} tty={tty}")

# 1回目の fork 、そして親プロセスを終了(ターミナルから切り離す)
pid = os.fork()
if pid > 0:
    log(f"[exit 1st parent] pid={os.getpid()}")
    os._exit(0)

# setsid() でセッションリーダーになる
os.setsid()
log(f"[setsid] pid={os.getpid()} sid={os.getsid(0)}")

# 2回目の fork、そして脱セッションリーダー
pid = os.fork()
if pid > 0:
    log(f"[exit 2nd parent] pid={os.getpid()}")
    os._exit(0)

# カレントディレクトリを / に変更(マウント保持防止)
os.chdir("/")

# 標準入出力を /dev/null にリダイレクト
fd = os.open('/dev/null', os.O_RDWR)
os.dup2(fd, 0)  # stdin
os.dup2(fd, 1)  # stdout
os.dup2(fd, 2)  # stderr

log(f"[daemon-ish] pid={os.getpid()} sid={os.getsid(0)}")
time.sleep(30)

ログの出力結果

# cat /logs/fork_test.log
[start] pid=13 ppid=7 sid=7 pgid=13 tty=/dev/pts/1 # tty 持ってる。親と同じセッション
[exit 1st parent] pid=13
[setsid] pid=14 sid=14 # 自分がセッションリーダーになった
[exit 2nd parent] pid=14 
[daemon-ish] pid=15 sid=14 # pid != SID なのでセッションリーダーではない

init 時代のデーモン

各サービスが、自分でデーモンのお作法を持つ必要があった。

このときの問題点:

  • 各プロセスが PID ファイルを自前で管理 → 競合や消し忘れの温床
  • ログを /var/log/xxx.log に書く → 出力先がバラバラで追跡が面倒
    • syslog といったログを統一的に管理するための仕組みも存在していたが、
      パフォーマンスや柔軟性の課題から、アプリケーション側で独自管理されるケースも多かった
  • プロセス監視や自動再起動を各自で工夫 → 品質・安定性に差が出る
  • スクリプトの依存関係(ネットワーク・DB など)を順番で解決していた ← しんどい

systemd 登場以降のデーモン

サービスは systemd に管理されることを前提として作られるようになり、お作法を持つことをやめた。

systemd に管理を任せることで、以下を自動でやってもらえるようになった:

  • サービスのデーモン化(バックグラウンド化)
  • セッションの儀式(TTY切断、親プロセスとの分離)
  • 自動再起動(Restart= オプション)
  • 起動順や依存関係の制御(After=, Requires=
  • リソース制御(CPU/メモリ制限)
  • ログの集約と一元管理(journalctl

→ サービス側は「フォアグラウンドで黙々と本業に専念するだけ」でよくなり、開発者の負担が大きく減った

おわりに

ここまでまとめてみての感想は、「デーモン化」とは単なるテクニックではなく、
プロセスが自分だけの責務に集中するために、環境とのつながりを意図的に断ち切る手順なんだな、と感じました。

セッションを断ち、TTY と別れ、親の手を離れ、自分の責務だけを静かに果たす――

そんなプロセスの旅路を、実際に ps を眺めたり、fork してみたりしながら追いかけたことで、ようやく頭の中に「構造」として定着してきたような気がします。

同じように「デーモンって何だろう……」と思っている人の助けになればうれしいです!

🔗 関連記事

14
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?