私はPythonで書かれたLaunchDaemonを持っており、root権限で長くてリソースを大量に消費するバックグラウンドタスクを実行します。それが機能するので、複数のGUIエージェント(ログインしたユーザーごとに1つ)にステータス更新を送信する必要があり、適切なIPCメカニズムを見つけるのに苦労しています。デーモンとエージェントは異なるブートストラップコンテキストで実行されるため、共有オブジェクトは機能しません。デーモンにソケットを開かせることはできません。デーモンは長期間応答できず、クライアントは更新をポーリングする必要があるためです。私が思いついた最善の方法は、各エージェントが独自のソケットを開き、デーモンが順番に各ソケットに書き込むことですが、それはせいぜいエレガントではないようです。他に選択肢はありますか?ああ、それはMac OSX10.5以降で動作する必要があります。
1 に答える
0
最終的に、各 GUI エージェントが /tmp の下にデータグラム ソケットを作成し、launchdaemon がメッセージをそれぞれに順番に送信し、古いソケットをクリーンアップします。
SOCKET_DIR = "/tmp"
SOCKET_NAME = "se.gu.it.dafgu_migration_status"
status_socket = None
def set_status_menu(status, message):
global status_socket
try:
if status_socket is None:
status_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
if status_socket is not None:
message = serializePlist({
"DAFGUMigrationStatus": status,
"DAFGUMigrationMessage": message,
})
for item in os.listdir(SOCKET_DIR):
if item.startswith(SOCKET_NAME):
socket_path = os.path.join(SOCKET_DIR, item)
logging.debug("Sending message to %s" % socket_path)
try:
status_socket.sendto(message, socket_path)
except socket.error, e:
if e[0] == errno.ECONNREFUSED:
logging.info("Removing stale socket %s" % socket_path)
os.unlink(socket_path)
else:
logging.warn("Sending to %s failed: %s" % (socket_path, e))
except BaseException, e:
logging.debug("Unhandled exception when updating status menu: %s" % e)
完全な実装は github で見つけることができます:
- https://github.com/MagerValp/DAFGU-rsync-wrapper (バックグラウンド プロセス)
- https://github.com/MagerValp/DAFGU-Migration-Status (GUI ステータス メニュー)
于 2012-11-19T09:19:32.710 に答える