菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
6
0

PPID=1 runs as a background process, rather than being under the direct control of an interactive user

原创
05/13 14:22
阅读数 20123

https://en.wikipedia.org/wiki/Daemon_(computing)

【后台进程,非互动】

d 结尾

syslogd 系统日志记录

sshd 响应ssh连接请求

 

 

In multitasking computer operating systems, a daemon (/ˈdmən/ or /ˈdmən/)[1] is a computer program that runs as a background process, rather than being under the direct control of an interactive user. Traditionally, the process names of a daemon end with the letter d, for clarification that the process is, in fact, a daemon, and for differentiation between a daemon and a normal computer program. For example, syslogd is the daemon that implements the system logging facility, and sshd is a daemon that serves incoming SSH connections.

In a Unix environment, the parent process of a daemon is often, but not always, the init process. A daemon is usually either created by a process forking a child process and then immediately exiting, thus causing init to adopt the child process, or by the init process directly launching the daemon. In addition, a daemon launched by forking and exiting typically must perform other operations, such as dissociating the process from any controlling terminal (tty). Such procedures are often implemented in various convenience routines such as daemon(3) in Unix.

【系统启动时,启动】

如对网络请求、硬件活动的响应

Systems often start daemons at boot time which will respond to network requests, hardware activity, or other programs by performing some task. Daemons such as cron may also perform defined tasks at scheduled times

https://zh.wikipedia.org/wiki/守护进程

在一个多任务的电脑操作系统中,守护进程(英语:daemon,/ˈdmən//ˈdmən/)是一种在后台执行的电脑程序。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。

通常,守护进程没有任何存在的父进程(即PPID=1),且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程运行fork,然后使其父进程立即终止,使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。

系统通常在启动时一同引导守护进程。守护进程为对网络请求,硬件活动等进行响应,或其他通过某些任务对其他应用程序的请求进行回应提供支持。守护进程也能够对硬件进行配置(如在某些Linux系统上的devfsd),运行计划任务(例如cron),以及运行其他任务。

DOS环境中,此类应用程序被称为驻留程序(TSR)。在Windows系统中,由称为Windows服务的应用程序来履行守护进程的职责。

在原本的Mac OS系统中,此类应用程序被称为“extensions”。而作为Unix-likeMac OS X有守护进程。(在Mac OS X中也有“服务”,但他们与Windows中类似的程序在概念上完全不相同。)

 

 

https://zh.wikipedia.org/wiki/父进程

计算机领域,父进程(英语:Parent Process)指已创建一个或多个子进程进程

 

UNIX

UNIX里,除了进程0(即PID=0的交换进程,Swapper Process)以外的所有进程都是由其他进程使用系统调用fork创建的,这里调用fork创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程。

操作系统内核进程标识符Process Identifier,即PID)来识别进程。进程0是系统引导时创建的一个特殊进程,在其调用fork创建出一个子进程(即PID=1的进程1,又称init)后,进程0就转为交换进程(有时也被称为空闲进程),而进程1(init进程)就是系统里其他所有进程的祖先。

僵尸进程与孤儿进程

当一个子进程结束运行(一般是调用exit、运行时发生致命错误或收到终止信号所导致)时,子进程的退出状态(返回值)会回报给操作系统,系统则以SIGCHLD信号将子进程被结束的事件告知父进程,此时子进程的进程控制块(PCB)仍驻留在内存中。一般来说,收到SIGCHLD后,父进程会使用wait系统调用以获取子进程的退出状态,然后内核就可以从内存中释放已结束的子进程的PCB;而如若父进程没有这么做的话,子进程的PCB就会一直驻留在内存中,也即成为僵尸进程

孤儿进程则是指父进程结束后仍在运行的子进程。在类UNIX系统中,孤儿进程一般会被init进程所“收养”,成为init的子进程。

为避免产生僵尸进程,实际应用中一般采取的方式是:

  1. 将父进程中对SIGCHLD信号的处理函数设为SIG_IGN(忽略信号);
  2. fork两次并杀死一级子进程,令二级子进程成为孤儿进程而被init所“收养”、清理[1]

Linux

Linux内核中,进程和POSIX线程有着相当微小的区别,父进程的定义也与UNIX不尽相同。Linux有两种父进程,分别称为(形式)父进程与实际父进程,对于一个子进程来说,其父进程是在子进程结束时收取SIGCHLD信号的进程,而实际父进程则是在多线程环境里实际创建该子进程的进程。对于普通进程来说,父进程与实际父进程是同一个进程,但对于一个以进程形式存在的POSIX线程,父进程和实际父进程可能是不一样的[2]

 

 

守护进程


ppid 1


https://unix.stackexchange.com/questions/240646/why-we-use-setsid-while-daemonizing-a-process

nohup 修改ppid 为1

 

https://pubs.opengroup.org/onlinepubs/7908799/xsh/setsid.html

 

 

https://github.com/karelzak/util-linux/blob/master/sys-utils/setsid.c

 

 

https://unix.stackexchange.com/questions/316186/how-does-nohup-work

 

 

 

The act of using nohup simply changes the PPID of the spawned process to 1 (init) so that when the shell exits, it is no longer a child process of that shell and so therefor doesn't receive a HUP.

EDIT: Should think more before I post sometimes. Leaving it here to remind me of my shame :-(

 

 

https://zh.wikipedia.org/wiki/孤儿进程

在操作系统领域中,孤儿进程(Orphan Process)指的是在其父进程执行完成或被终止后仍继续运行的一类进程

 

解决办法

“收养”

类UNIX操作系统中,为避免孤儿进程退出时无法释放所占用的资源而僵死,任何孤儿进程产生时都会立即为系统进程initsystemd自动接收为子进程,这一过程也被称为“收养”(英语:re-parenting)[1]。在此需注意,虽然事实上该进程已有init作为其父进程,但由于创建该进程的进程已不存在,所以仍应称之为“孤儿进程”。

进程组

因为父进程终止或崩溃都会导致对应子进程成为孤儿进程,所以也无法预料一个子进程执行期间是否会被“遗弃”。有鉴于此,多数类UNIX系统都引入了进程组以防止产生孤儿进程:在父进程终止后,用户的Shell会将父进程所在进程组标为“孤儿进程组”,并向终止的进程下属所有子进程发出SIGHUP信号,以试图结束其运行,如此避免子进程继续以“孤儿进程”的身份运行[2]

远程调用的情况

RPC过程中也会产生孤儿进程。例如,若客户端进程在发起请求后突然崩溃,且对应的服务器端进程仍在运行,则该服务器端进程就会成为孤儿进程。这样的孤儿进程会浪费服务器的资源,甚至有耗尽资源的潜在危险,但也有对应的解决办法[3]

  1. 终止机制:强制杀死孤儿进程(最常用的手段);
  2. 再生机制:服务器在指定时间内查找调用的客户端,若找不到则直接杀死孤儿进程;
  3. 超时机制:给每个进程指定一个确定的运行时间,若超时仍未完成则强制终止之。若有需要,亦可让进程在指定时间耗尽之前申请延时。

“孤儿进程”的应用

除此之外,用户也可能会刻意使进程成为孤儿进程,以使之与用户会话脱钩,并转至后台运行。这一做法常应用于启动需要长时间运行的进程,也即守护进程[4]。另外,UNIX命令nohup也可以完成这一操作[5]

 

 

https://linux.die.net/man/3/execvp

The exec() family of functions replaces the current process image with a new process image. The functions described in this manual page are front-ends for execve(2). (See the manual page for execve(2) for further details about the replacement of the current process image.)

The initial argument for these functions is the name of a file that is to be executed.

 

 

https://zh.wikipedia.org/wiki/进程ID

计算机领域,进程标识符(英语:process identifier,又略称为进程ID(英语:process ID)、PID)是大多数操作系统内核用于唯一标识进程的一个数值。这一数值可以作为许多函数调用的参数,以使调整进程优先级、杀死进程之类的进程控制行为成为可能。

类UNIX系统

类UNIX操作系统中,新进程都衍自系统调用fork()fork()调用会将子进程的PID返回给父进程,使其可以之指代子进程,从而在需要时以之为函数参数。例如,若以子进程PID为参数调用waitpid(),可使父进程以休眠状态等待子进程结束;若以之为参数调用kill(),便可结束对应子进程。

在各PID中,较为特别的是0号PID和1号PID。PID为0者为交换进程(英语:swapper),属于内核进程,负责分页任务;PID为1者则常为init进程,主要负责启动与关闭系统。值得一提的是,1号PID本来并非是特意为init进程预留的,而init进程之所以拥有这一PID,则是因为init即是内核创建的第一个进程。不过,现今的许多UNIX/类UNIX系统内核也有以进程形式存在的其他组成部分,而在这种情况下,1号PID则仍为init进程保有,以与之前系统保持一致[1]

PID的分配机制则因系统而异,一般从0开始,然后顺序分配,直到达到一个最大值(亦因系统而异),而后又从300开始重新分配;在Mac OS XHP-UX下,则是由100开始重分配。在分配PID时,若遇到已分配的PID,则直接跳过,继续递增查找下一个可分配PID。

Microsoft Windows

Microsoft Windows系列操作系统提供了一系列API,以使开发者可以获取相关PID,如用于获取当前进程PIDGetCurrentProcessId()[2]、返回其他进程PID的GetProcessId()[3]。在操作系统内部,进程ID与线程ID在同一个名字空间中,因此二者不会重合。

PID文件

有些长时间运行的进程(如MySQL的守护进程)会将自己的PID写入一个文件,以使其他进程可寻获之。

参见

https://en.wikipedia.org/wiki/Process_identifier

In computing, the process identifier (a.k.a. process ID or PID) is a number used by most operating system kernels—such as those of UnixmacOS and Windows—to uniquely identify an active process. This number may be used as a parameter in various function calls, allowing processes to be manipulated, such as adjusting the process's priority or killing it altogether.

Unix-like

In Unix-like operating systems, new processes are created by the fork() system call. The PID is returned to the parent process, enabling it to refer to the child in further function calls. The parent may, for example, wait for the child to terminate with the waitpid() function, or terminate the process with kill().

There are two tasks with specially distinguished process IDs: swapper or sched has process ID 0 and is responsible for paging, and is actually part of the kernel rather than a normal user-mode process. Process ID 1 is usually the init process primarily responsible for starting and shutting down the system. Originally, process ID 1 was not specifically reserved for init by any technical measures: it simply had this ID as a natural consequence of being the first process invoked by the kernel. More recent Unix systems typically have additional kernel components visible as 'processes', in which case PID 1 is actively reserved for the init process to maintain consistency with older systems.

Process IDs, in the first place, are usually allocated on a sequential basis, beginning at 0 and rising to a maximum value which varies from system to system. Once this limit is reached, allocation restarts at 300 and again increases. In macOS and HP-UX, allocation restarts at 100. However, for this and subsequent passes any PIDs still assigned to processes are skipped. Some consider this to be a potential security vulnerability in that it allows information about the system to be extracted, or messages to be covertly passed between processes. As such, implementations that are particularly concerned about security may choose a different method of PID assignment.[1] On some systems, like MPE/iX, the lowest available PID is used, sometimes in an effort to minimize the number of process information kernel pages in memory.

The current process ID is provided by a getpid() system call, or as a variable $$ in shell. The process ID of a parent process is obtainable by a getppid() system call.

On Linux, the maximum process ID is given by the pseudo-file /proc/sys/kernel/pid_max.[2]

Pidfile

Some processes, for example, the moc music player and the MySQL daemon, write their PID to a documented file location, to allow other processes to look it up.

Microsoft Windows

On the Windows family of operating systems, one can get the current process's ID using the GetCurrentProcessId() function of the Windows API,[3] and ID of other processes using GetProcessId().[4] Internally, process ID is called a client ID, and is allocated from the same namespace as thread IDs, so these two never overlap. The System Idle Process is given process ID 0. The System Process is given the process ID 8 on Windows 2000 and 4 on Windows XP and Windows Server 2003.[5] On the Windows NT family of operating systems, process and thread identifiers are all multiples of 4, but it is not part of the specification.[6]

See also

发表评论

0/200
6 点赞
0 评论
收藏