PWN December 29, 2020

linux下的对进程的学习

Words count 9.3k Reading time 8 mins. Read count 0

一、什么是进程?

就是操作系统为了实现某些功能进行的分身术,生成的子进程可以进行相应的工作

创建进程最基本的调用是fork

1
2
3
# include <unistd.h>
pid_t fork(void);
pid_t vfork(void);

调用 fork 时,系统将创建一个与当前进程相同的新进程。通常将原有的进程称为父进程,把新创建的进程称为子进程。子进程是父进程的一个拷贝,子进程获得同父进程相同的数据,但是同父进程使用不同的数据段和堆栈段。子进程从父进程继承大多数的属性,但是也修改一些属性,下表对比了父子进程间的属性差异:

image-20201229220959486

fork 函数的特点是 “调用一次,返回两次”:在父进程中调用一次,在父进程和子进程中各返回一次。在父进程中返回时的返回值为子进程的 PID,而在子进程中返回时的返回值为 0,并且返回后都将执行 fork 函数调用之后的语句。如果 fork 函数调用失败,则返回值为 -1

了。来看个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
pid_t pid;
char *message;
int n;
pid = fork();
if(pid < 0)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
printf("This is the child process. My PID is: %d. My PPID is: %d.\n", getpid(), getppid());
}
else
{
printf("This is the parent process. My PID is %d.\n", getpid());
}
return 0;
}

如果要在子进程中执行命令的话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
if((pid=vfork()) < 0)
{
printf("vfork error!\n");
exit(1);
}
else if(pid==0)
{
printf("Child process PID: %d.\n", getpid());
char *argv[ ]={"ls", "-al", "/home", NULL};
char *envp[ ]={"PATH=/bin", NULL};
if(execv("/bin/ls", argv, envp) < 0)
{
printf("subprocess error");
exit(1);
}
// 子进程要么从 ls 命令中退出,要么从上面的 exit(1) 语句退出
// 所以代码的执行路径永远也走不到这里,下面的 printf 语句不会被执行
printf("You should never see this message.");
}
else
{
printf("Parent process PID: %d.\n", getpid());
sleep(1);
}
return 0;
}
0%