一、进程的介绍
程序是静态的概念,例如:gcc process.c -o pro,意思是在磁盘中生成一个叫 pro 的文件,这个就叫程序;进程是动态的概念,程序跑起来就叫进程,每运行一个程序,系统就多一个进程。
1.1.进程标识符
pid:Process IDentifier(进程标识符),它是操作系统分配给每个进程的一个唯一数字标识,用于在系统内区分和管理不同的进程。它的特点有:
- 在同一时刻,系统内每个进程的 pid 都是唯一的
- 但当进程结束后,其 pid 可以被系统回收并重新分配给新进程
- 在 Linux 中,pid 通常是一个从 1 开始递增的整数
在 Ubuntu 的终端里,通过输入ps -aux查看所有进程:

通过调用以下函数可知某一时刻的进程标识符:
- pid_t getpid(void) - 返回当前进程的 pid
- pid_t getppid(void) - 返回父进程的 pid
- pid_t fork(void) - 创建新进程,返回子进程的 pid(在父进程中)
1.2.父进程与子进程
在一个进程里又创建一个新的进程,创建的叫做父进程,被创建的叫做子进程。在一个程序里想要创建一个新的进程,可以通过pid_t fork(void);函数创建,该函数的返回值如果为 -1 说明创建进程失败,如果返回值为 0 说明正在执行子进程,如果返回值大于 0 说明在执行父进程。在调用该函数之后,执行父进程时,返回值为子进程的 pid。
- 将子进程ID返回给父进程的理由是:因为一个进程的子进程可以有多个,并且没有一个函数使一个进程可以获得其所有子进程的进程ID。fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用 getppid 以获得其父进程的进程 ID (进程 ID 0 总是由内核交换进程使用,所以一个子进程的进程 ID 不可能为 0)。
1.3.父子进程的内存关系
在以前的 Linux 父子进程中,子进程完全复制父进程的地址空间,如下如所示,将所有的信息都复制了一份,这会导致内存浪费和性能开销

现代的处理方法是写时复制:多个调用者需要共享相同的资源时,只有在真正需要修改时才会进行复制,否则一直共享,这样大幅提升性能,减少内存开销。
二、软件实现
使用父子进程实现服务器的功能,当用户输入 1 时,创建一个新的进程,并且在此进程对用户进行服务,并打印进程标识符:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid;
int data;
while(1)
{
printf("Please input a data:\n");
scanf("%d", &data);
if(data == 1)
{
pid = fork();
if(pid == 0)
{
while(1)
{
printf("Hello!!!\n");
printf("Your pid is:%d\n", getpid());
sleep(5);
}
}
}
else
{
printf("Waiting for your correct answer\n");
}
}
return 0;
}
7323

被折叠的 条评论
为什么被折叠?



