如何知道进程是父进程还是子进程
How to know if a process is a parent or a child
如何使用 pid
识别一个进程是否是另一个进程的 child/grandchild?
进程 ID:Child- 和 parent 个进程
所有 运行 程序都有唯一的进程 ID。这
process ID,一个
non-negative 整数,是进程的唯一标识符
始终 独一无二。但是,进程 ID 被重复使用。
当一个进程终止时,它的 ID 变得可以重复使用。肯定
系统延迟重用,这样新创建的进程就不会混淆
和旧的。
某些 ID 是 "reserved",因为它们被
系统进程,例如 scheduler 进程。另一个例子是
init 始终占用PID 1的进程。取决于系统
该 ID 可能已被主动保留。
运行 命令
> ps -eaf | head -n 5
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:49 ? 00:00:02 /sbin/init splash
root 2 0 0 11:49 ? 00:00:00 [kthreadd]
root 3 2 0 11:49 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 11:49 ? 00:00:00 [kworker/0:0H]
和
> pidof init
1
将允许您独立验证这一点。1
在C中我们可以使用以下函数来获取进程ID
调用进程和调用进程的 parent 进程 ID,
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
一个进程可以创建其他进程。创建的进程称为
“child 进程”,我们将创建它们的进程称为
“parent 过程”。
使用 fork() 创建新进程
要创建一个 child 进程,我们使用系统调用
fork()
#include <unistd.h>
pid_t fork(void);
该函数被 parent 进程调用一次,但它 returns
两次。 child进程中的return值为0,return
parent进程中的值是新child.1
的进程ID
一个进程可以有多个child进程但是没有系统
调用进程获取其所有 children 的进程 ID,因此
parent 观察 child 进程的 return 值,可以使用
这些标识符来管理它们。
一个进程只能有一个parent进程,总是
可通过调用 getppid
.
获得
child 是 parent 的 copy,它得到 copy 117=]的
数据 space、堆和堆栈。他们不分享这些部分
记忆! 2
我们将编译并执行以下代码片段,看看如何
这有效,
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
int main(void) {
int var = 42; // This variable is created on the stack
pid_t pid;
// Two processes are created here
// v~~~~~~~~~~|
if ((pid = fork()) < 0) {
perror("Fork failed");
} else if (pid == 0) { // <- Both processes continue executing here
// This variable gets copied
var++;
printf("This is the child process:\n"
"\t my pid=%d\n"
"\t parent pid=%d\n"
"\t var=%d\n", getpid(), getppid(), var);
} else {
printf("This is the parent process:\n"
"\t my pid=%d\n"
"\t child pid=%d\n"
"\t var=%d\n", getpid(), pid, var);
}
return 0;
}
我们将在执行程序时看到没有任何保证
至于哪个进程首先执行。他们甚至可能经营
同时,有效地交织他们的输出。 3
$ # Standard compilation
$ gcc -std=c99 -Wall fork_example1.c -o fork_example1
$ # Sometimes the child executes in its entirety first
$ ./fork_example1
This is the child process:
my pid=26485
parent pid=26484
var=43
This is the parent process:
my pid=26484
child pid=26485
var=42
$ # and sometimes the parent executes in its entirety first
$ ./fork_example1
This is the parent process:
my pid=26461
child pid=26462
var=42
This is the child process:
my pid=26462
parent pid=26461
var=43
$ # At times the two might interleave
$ ./fork_example1
This is the parent process:
my pid=26455
This is the child process:
my pid=26456
parent pid=26455
var=43
child pid=26456
var=42
1 PID代表进程ID和PPID代表
Parent 进程 ID.
2进程ID 0是保留给内核使用的,所以
0 不可能是 child.
的进程 ID
3很多系统不执行这些的完整拷贝
内存段,而不是仅在任一进程时创建副本
执行写入。最初,共享区域由
内核为 "read-only" 并且每当一个进程试图修改这些
区域内核授予每个进程自己的内存副本。
4 标准输出是 缓冲 所以这不是一个完美的例子。
使用getpid()和getppid()函数获取进程id和父进程id。
如何使用 pid
识别一个进程是否是另一个进程的 child/grandchild?
进程 ID:Child- 和 parent 个进程
所有 运行 程序都有唯一的进程 ID。这 process ID,一个 non-negative 整数,是进程的唯一标识符 始终 独一无二。但是,进程 ID 被重复使用。
当一个进程终止时,它的 ID 变得可以重复使用。肯定 系统延迟重用,这样新创建的进程就不会混淆 和旧的。
某些 ID 是 "reserved",因为它们被 系统进程,例如 scheduler 进程。另一个例子是 init 始终占用PID 1的进程。取决于系统 该 ID 可能已被主动保留。
运行 命令
> ps -eaf | head -n 5
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:49 ? 00:00:02 /sbin/init splash
root 2 0 0 11:49 ? 00:00:00 [kthreadd]
root 3 2 0 11:49 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 11:49 ? 00:00:00 [kworker/0:0H]
和
> pidof init
1
将允许您独立验证这一点。1
在C中我们可以使用以下函数来获取进程ID 调用进程和调用进程的 parent 进程 ID,
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
一个进程可以创建其他进程。创建的进程称为 “child 进程”,我们将创建它们的进程称为 “parent 过程”。
使用 fork() 创建新进程
要创建一个 child 进程,我们使用系统调用
fork()
#include <unistd.h>
pid_t fork(void);
该函数被 parent 进程调用一次,但它 returns 两次。 child进程中的return值为0,return parent进程中的值是新child.1
的进程ID一个进程可以有多个child进程但是没有系统 调用进程获取其所有 children 的进程 ID,因此 parent 观察 child 进程的 return 值,可以使用 这些标识符来管理它们。
一个进程只能有一个parent进程,总是
可通过调用 getppid
.
child 是 parent 的 copy,它得到 copy 117=]的 数据 space、堆和堆栈。他们不分享这些部分 记忆! 2
我们将编译并执行以下代码片段,看看如何 这有效,
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
int main(void) {
int var = 42; // This variable is created on the stack
pid_t pid;
// Two processes are created here
// v~~~~~~~~~~|
if ((pid = fork()) < 0) {
perror("Fork failed");
} else if (pid == 0) { // <- Both processes continue executing here
// This variable gets copied
var++;
printf("This is the child process:\n"
"\t my pid=%d\n"
"\t parent pid=%d\n"
"\t var=%d\n", getpid(), getppid(), var);
} else {
printf("This is the parent process:\n"
"\t my pid=%d\n"
"\t child pid=%d\n"
"\t var=%d\n", getpid(), pid, var);
}
return 0;
}
我们将在执行程序时看到没有任何保证 至于哪个进程首先执行。他们甚至可能经营 同时,有效地交织他们的输出。 3
$ # Standard compilation
$ gcc -std=c99 -Wall fork_example1.c -o fork_example1
$ # Sometimes the child executes in its entirety first
$ ./fork_example1
This is the child process:
my pid=26485
parent pid=26484
var=43
This is the parent process:
my pid=26484
child pid=26485
var=42
$ # and sometimes the parent executes in its entirety first
$ ./fork_example1
This is the parent process:
my pid=26461
child pid=26462
var=42
This is the child process:
my pid=26462
parent pid=26461
var=43
$ # At times the two might interleave
$ ./fork_example1
This is the parent process:
my pid=26455
This is the child process:
my pid=26456
parent pid=26455
var=43
child pid=26456
var=42
1 PID代表进程ID和PPID代表 Parent 进程 ID.
2进程ID 0是保留给内核使用的,所以 0 不可能是 child.
的进程 ID3很多系统不执行这些的完整拷贝 内存段,而不是仅在任一进程时创建副本 执行写入。最初,共享区域由 内核为 "read-only" 并且每当一个进程试图修改这些 区域内核授予每个进程自己的内存副本。
4 标准输出是 缓冲 所以这不是一个完美的例子。
使用getpid()和getppid()函数获取进程id和父进程id。