守护进程精灵进程参考资料《Linux高级程序设计》1.1概念守护进程Daemon是在计算机操作系统中以后台形式运行的一类特殊进程。它们在系统启动时被启动一直运行在后台不依赖于任何用户交互也不与任何终端相关联。守护进程的主要目标是提供一种持续运行的服务通常用于执行一些系统级任务或提供特定的功能和服务。例如守护进程可以用于管理网络服务、定时任务、系统监控、日志记录等。它们通常作为系统的一部分在操作系统启动时通过启动脚本或系统配置文件自动启动并且在系统关闭前会被自动终止。守护进程通常以父进程通常是init进程的方式运行并且它们会脱离终端的控制。这意味着它们不会受到用户登录会话的影响不会受用户注销或终端断开的影响而且不会向终端输出任何信息。此外守护进程通常会将自己的运行日志写入日志文件以便后续的故障排查和日志分析。它们在运行期间往往以系统权限运行以便执行系统级任务因此需要注意确保安全性。总结来说守护进程是在后台以系统服务的形式持续运行的特殊进程。它们在系统启动时自动启动不依赖于用户交互和终端主要用于执行系统级任务和提供特定的功能和服务。1.2作用守护进程Daemon在计算机系统中扮演着重要的角色具有以下几个主要作用提供持续性服务守护进程通常用于提供持续性的服务这些服务在系统运行期间一直保持运行状态。通过守护进程可以实现后台任务的自动化执行例如服务的启动和停止定时任务的执行系统监控和维护等。后台处理任务守护进程通常用于执行一些需要在后台处理的任务。它们不依赖于用户交互和终端可以在系统运行期间持久地进行工作。这主要包括一些系统级任务如网络服务、文件处理、日志记录、备份、数据同步等。提供服务和功能守护进程用于提供特定的服务和功能。这些服务可以是网络相关的如Web服务器、FTP服务器、邮件服务器等也可以是系统级的如定时任务调度器、系统监控服务、日志收集器等。通过守护进程可以将这些功能以持续、自动化的方式提供给用户。系统维护和管理守护进程还用于系统的维护和管理。它们可以监视系统的运行状态及时处理和报告问题。例如守护进程可以监控硬件故障、内存和硬盘使用情况提供警报和日志记录。同时守护进程也可以协助系统管理员进行系统配置和管理实现对系统资源的优化和控制。总的来说守护进程在计算机系统中承担着重要的角色用于提供持续性服务、后台处理任务、提供特定的服务和功能以及系统维护和管理。它们使得系统能够实现自动化、高效、稳定地执行各种任务提供良好的用户体验和系统性能。1.3特点守护进程Daemon具有以下几个特点后台运行守护进程以后台形式运行不依赖于任何用户交互或终端。它们在系统启动时被自动启动并在系统运行期间持续执行。这使得它们可以在系统运行期间提供服务和执行任务而无需用户干预或终端的打开。脱离终端守护进程与任何终端无关不会与终端进行交互。它们不会向终端输出任何信息也不会接收来自终端的输入。这意味着守护进程在后台默默地执行任务不会干扰用户的终端会话。生命周期长守护进程在系统启动时被创建并持续运行直至系统关闭或手动终止。它们通常以父进程的方式运行由系统的init进程或其他启动脚本完成启动。守护进程的长生命周期使得它们能够提供持续性的服务处理长时间运行的任务。不受用户会话影响守护进程与用户会话无关不受用户登录、注销或会话断开的影响。它们以系统级的身份运行拥有独立的运行环境和权限。这使得守护进程能够在系统运行期间持续提供服务和执行任务独立于特定用户或会话的状态。日志记录守护进程通常会将自己的运行日志写入特定的日志文件中。这些日志记录包含守护进程运行的详细信息用于故障排查、性能分析和系统监控。日志记录可以帮助系统管理员了解守护进程的运行状况发现问题并进行相应的处理。总的来说守护进程以后台形式运行脱离终端具有长生命周期不受用户会话影响同时也会进行日志记录。这些特点使得守护进程能够在系统运行期间提供持续性的服务执行后台任务并具备独立的运行环境和权限。1.4编程步骤创建子进程并终止父进程使用 fork() 系统调用创建一个子进程并在父进程中使用 exit() 函数终止确保子进程可以继续执行。在子进程中创建新会话和新进程组使用 setsid() 系统调用创建一个新的会话并使当前进程成为新会话的领导进程。这样可以脱离终端会话避免受到终端信号的影响。设置文件掩码使用 umask() 系统调用设置文件掩码通过屏蔽某些权限位来限制新建文件的默认权限。比如调用 umask(0) 将文件掩码设置为0即不屏蔽任何权限位。更改工作目录使用 chdir() 系统调用将当前工作目录切换到一个合适的目录一般选择一个不会被卸载的目录例如根目录 /。关闭文件描述符由于守护进程不再需要与终端交互需要关闭标准输入、标准输出和标准错误输出的文件描述符。可以使用 close() 系统调用关闭这些文件描述符。执行任务并处理信号在守护进程中执行自己的任务逻辑如网络服务或定时任务。同时需要注册信号处理函数处理来自操作系统的信号如重新加载配置或优雅地终止。请注意编写守护进程时除了上述步骤外还应注意错误处理、日志记录和安全性等方面的问题。最好参考特定编程语言和操作系统的文档和示例代码以获取更详细的实现细节。理解守护进程要了解一下 会话进程组。简单代码getpid获取当前进程idgetsid获取会话idgetpgrp获取组id在同一个终端里会话id相同。看sid等于bash的pid,则bash的进程就是进程组组长因为每次打开终端bash进程就会执行。当我们fock一下父子的gid相同他们就在同一个进程组里。守护进程是用来避免我们把终端关闭时进程依然在执行。使进程不依附于终端服务器上就需要这样的操作。编程流程1.fock退出父进程留下子进程。2.setsid()创建新会话则我们这个进程就是新会话的会话组长也是进程组组长这也是为啥我们要留下子进程防止父进程是原来会话的会话组长或进程组组长导致两个会话共用同一个id这样是不合理的。3.fock退出父进程丢弃会话组长和进程组长的身份在新会话里该子进程就变成父进程退出父进程留下子进程防止一些可能的失误这一步也可以不写类似指针判空的意义4.chdir(“/”),将路径切换到根下面防止被卸载5.umask(0),清空掩码就是改权限上面有6.close(),关闭文件描述符连标准输入输出都关闭我们也不用7.若产生僵尸进程则还要处理僵尸进程Windows里面守护进程叫服务咱们看不到图形化界面没有交互代码实现实现文件里写入时间文件命名通常在后面加个d表示是守护进程eg : maind.c代码#includestdio.h#includeunistd.h#includestring.h#includetime.hintmain(){pid_tpidfork();if(pid!0)//父进程推出exit(1);setsid();//创建新会话这里就进入了新会话pidfork();//不是必须的对应上面步骤3if(pid!0)exit(1);chdir(/);umask(0);intmaxfdgetdtablesize();//获取最大文件描述符挨个关闭for(inti0;imaxfd;i){clode(i);}while(1){time_ttv;time(tv);FILE*fpfopen(/tmp/c2405d.log,a);if(fpNULL)break;fprintf(fp,time is %s,asctime(localtime(tv)));fclose(fp);sleep(5);}}就是在/tmp/c2405d.log文件里写时间。我们敲ps只显示当前终端里的进程所以看不见该进程用ps -ef来看所有进程命令tail -f 可以打印出来文件里不同的内容天生是用来看日志文件ctrlc结束想要结束守护进程用kill即可