MAC os开发

mac守护进程

2017-03-10  本文已影响952人  EnjoyWT
1. launchd

Mac系统下通用的进程管理器,是Mac系统下非常重要的一个进程,一般来说该进程不允许直接以命令行的形式调用。只能通过其控制管理界面,launchctl来进行控制。
launchd主要功能是进程管理。可以理解成是一个常驻在后台的进程,根据用户的配置,来响应特定的系统事件。launchd既可以用于系统级别的服务,又可以用于个人用户级别的服务。

2. 在launchd的语境中,常驻进程有两种:
daemon  # 也就是我们常说的守护进程,这种一般对所有用户都有相同的行为,响应相同的事件,始终运行于后台,没有前台交互界面。
agent   # 这种是用户级别的服务进程,一般以用户的身份运行。
3. 守护进程(daemon)

是指在UNIX或其他多任务操作系统中在后台执行的电脑程序,并不会接受电脑用户的直接操控。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。
通常,守护进程没有任何存在的父进程(即PID=1),且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程调用fork,然后使其父进程立即终止,使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。
系统通常在启动时一同起动守护进程。守护进程为对网络请求,硬件活动等进行响应,或其他通过某些任务对其他应用程序的请求进行回应提供支持。守护进程也能够对硬件进行配置(如在某些Linux系统上的devfsd),运行计划任务(例如cron),以及运行其他任务。

4. Mac的守护进程目录有以下几处:
~/Library/LaunchAgents  # 用户的进程
/Library/LaunchAgents   # 管理员设置的用户进程
/Library/LaunchDaemons  # 管理员提供的系统守护进程
/System/Library/LaunchAgents    # Mac操作系统提供的用户进程
/System/Library/LaunchDaemons   # Mac操作系统提供的系统守护进程

以上是launchd的相关配置的存放目录,可以看到,一般我们个人编写的守护进程,都应该放到~/Library/LaunchAgents目录里面。

将定时任务加入系统
#首先要把plist文件放入对相应的目录中(参看4. Mac的守护进程目)
# 加载 your.plist
$ launchctl load /Library/LaunchAgents/your.plist
//添加后进程会直接运行,不用重启电脑

#######查看服务运行状态

$ launchctl list 
PID  Status  Label
-    0    yourLabelName


如果移除移除的话

# 移除 xyz.hanks.spider
$ launchctl unload  /Library/LaunchAgents/your.plist
5.plist文件键值
键值 描述(作用)
Label <string> 必选, 进程的名字唯一标示符
Program <string> 要运行的程序, 如果省略这个选项,会把ProgramArguments的第一个元素作为要运行的程序, 任务执行绝对路径
ProgramArguments <array of strings> 字段值会作为Program <string>的参数传入(一般把任务写成可执行文件, 然后紧跟参数),
KeepAlive <boolean or dictionary of stuff> 必选, 是否持续执行任务
WatchPaths <array of strings> 可选, 作用:监听路径. 当任何一个被监听的路径(array中指定的string)被修改时,都会重启任务
QueueDirectories <array of strings> 可选, 和WatchPaths的作用很像,作用是监听路径的修改. 不同之处是,只有这个路径是一个目录并且这个目录不为空时 ,任务才会被重启.
StartOnMount <boolean> This optional key causes the job to be started every time a filesystem is mounted. 具体作用未明
StartInterval <integer> 可选, 每间隔 N 秒 重启任务. 当系统是睡眠状态时,任务会在下次系统被唤醒时重启,睡眠时的多个任务重启事件会被合并成一个事件 (系统睡眠时,无论多少个N秒,系统被唤醒时只会执行一次)
StartCalendarInterval <dictionary of integers or array of dictionary of integers> 可选, 在指定的日历格式的时间点 重启任务, 缺少的参数会被当做通配符(对应参数时间段内任意时间点), 这个命令和 crontab 命令很像(在系统休眠是也会执行任务), 和 corn (系统休眠时不执行任务,系统被唤醒时,多次执行命令合并成一次.同StartInterval <integer>) 不一样. 参数格式详见下 附表2
StandardInPath <string> 可选, 执行任务的标准数据输入的文件路径
StandardOutPath <string> 可选, 任务执行时保存标准输出的文件路径
StandardErrorPath <string> 可选, 任务执行时,保存错误日志的文件路径
Debug <boolean> 可选, 当任务执行,launchd 将临时的调整它的日志mask到LOG_DEBUG
附表2
键值 描述
Minute <integer> 第几分钟时执行任务
Hour <integer> 第几个小时执行任务(采用24时制)
Day <integer> 每个月的第几天执行任务
Weekday <integer> 周几执行任务,(0~7)
Month <integer> 第几个月执行任务

苹果官方文档

6定时任务样例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>

    <key>Label</key>
    <string>xyz.hanks.spider</string>

    <!-- 要运行的程序, 如果省略这个选项,会把ProgramArguments的第一个
    元素作为要运行的程序 -->
    <key>Program</key>
    <string>/Users/zhanks/work/Bookshelf/run.sh</string>

    <!-- 每天18:30 -->
    <key>StartCalendarInterval</key>
    <dict>
        <key>Minute</key>
        <integer>30</integer>
        <key>Hour</key>
        <integer>18</integer>
    </dict>
    <!-- 运行间隔,与StartCalenderInterval使用其一,单位为>秒 -->
    <!-- <key>StartInterval</key>-->
    <!-- integer>5</integer>-->

    <!-- 标准错误输出文件,错误日志 -->
    <key>StandardErrorPath</key>
    <string>/Users/zhanks/run-err.log</string>

  </dict>
</plist>

其他定时任务plist文件
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
  <dict>
    
    <key>Label</key>
    <!-- 名称,要全局唯一 -->
    <string>xyz.hanks.spider</string> 

    <!-- 要运行的程序, 如果省略这个选项,会把ProgramArguments的第一个
    元素作为要运行的程序 -->
    <key>Program</key>
    <string>/Users/hanks/run.sh</string>

    <!-- 命令, 第一个为命令,其它为参数-->
    <key>ProgramArguments</key>
    <array>
      <string>/Users/hanks/run.sh</string>
    </array>

    <!-- 运行时间 -->
    <key>StartCalendarInterval</key>
    <dict>

      <key>Minute</key>
      <integer>30</integer>

      <key>Hour</key>
      <integer>9</integer>

      <key>Day</key>
      <integer>1</integer>

      <key>Month</key>
      <integer>5</integer>

      <!-- 0和7都指星期天 -->
      <key>Weekday</key>
      <integer>0</integer>

    </dict>

    <!-- 运行间隔,与StartCalenderInterval使用其一,单位为秒 -->
    <key>StartInterval</key>
    <integer>30</integer>

    <!-- 标准输入文件 -->
    <key>StandardInPath</key>
    <string>/Users/hanks/run-in.log</string>

    <!-- 标准输出文件 -->
    <key>StandardOutPath</key>
    <string>/Users/hanks/run-out.log</string>

    <!-- 标准错误输出文件 -->
    <key>StandardErrorPath</key>
    <string>/Users/hanks/run-err.log</string>
  </dict>  
</plist>
自测例子
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>wxx.example</string>
    <key>StandardErrorPath</key>
    <string>/Users/computername/Desktop/eeee.txt</string>
    <key>StandardOutPath</key>
    <string>/Users/computername/Desktop/eeee.txt</string>
    <key>KeepAlive</key>
    <true/>
    <key>ProgramArguments</key>
    <array>
        <string>python</string>
        <string>/Users/computername/Desktop/tests/test.py</string>
    </array>
</dict>
</plist>

资料来源:

1. Mac 上利用 launchctl 开启定时任务
2. crontab 定时任务

上一篇下一篇

猜你喜欢

热点阅读