Linux学习-进程概念
基本概念
进程是程序的一次动态执行过程—— 它不仅包含了程序本身的代码和数据,还涵盖了执行过程中所需的资源(如内存、CPU 时间、文件句柄等)和状态信息,是操作系统进行资源分配和调度的基本单位。
描述进程PCB
- 进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合
- 称为PCB(processcontrolblock),Linux操作系统下的PCB是task_struct(PCB的一种),是一个描述进程的结构体
- task_struct 是Linux 内核的⼀种数据结构类型,它会被装载到RAM(内存)⾥并且包含着进程的信息
task_ struct
内容分类
- 标示符:描述本进程的唯⼀标⽰符,⽤来区别其他进程。
- 状态:任务状态,退出代码,退出信号等。
- 优先级:相对于其他进程的优先级。
- 程序计数器:程序中即将被执⾏的下⼀条指令的地址。
- 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- 上下⽂数据:进程执⾏时处理器的寄存器中的数据。
- I∕O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。
- 记账信息:可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
- 其他信息等
组织进程
内核源代码里可以找到。所有运⾏在系统里的进程都以task_struct 双链表的形式存在内核类里

查看进程
- 进程的信息可以通过如/proc 系统⽂件夹查看

- 进程信息同样可以使⽤top和ps这些⽤⼾级⼯具来获取
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
while(1)
{
sleep(1);
}
return 0;
}

系统调⽤获取进程标⽰符
- 进程id(pid)
- 父进程id(ppid)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}

系统调⽤创建进程-fork初识
fork

fork是 Unix/Linux 系统中用于创建新进程的系统调用,其核心功能是复制当前进程(父进程),生成一个全新的子进程。子进程几乎是父进程的完全副本,但拥有独立的进程 ID(PID)和资源空间。

- 调用一次,返回两次
- 父进程中:fork() 返回子进程的 PID(大于 0 的整数)
- 子进程中:fork() 返回 0。
- 若失败(如资源不足):返回 -1(仅父进程会收到错误)。
- 子进程的复制范围
- 复制父进程的代码段、数据段、堆、栈、文件描述符(共享文件指针)、环境变量等。
- 子进程与父进程共享代码段(只读),但数据段、堆、栈是独立副本(写时复制,COW 机制优化效率)。
int main()
{
int ret = fork();
printf("hello proc : %d!, ret: %d\n", getpid(), ret);
sleep(1);
return 0;
}

- fork之后通常要⽤if进⾏分流
int main()
{
int ret = fork();
while (1)
{
/* code */
if (ret > 0)
{
printf("这是父进程,fork()返回: %d!, 该进程pid: %d,父进程pid: %d\n", ret, getpid(), getppid());
sleep(1);
}
else if (ret == 0)
{
printf("这是子进程,fork()返回: %d!,该进程pid: %d,父进程pid: %d\n", ret, getpid(), getppid());
sleep(1);
}
else
{
perror("fork");
return -1;
}
}
return 0;
}
因为父、子进程的fork()各自返回不同的ret,所以在执行if语句时会进入不同的分支
return -1;
}
}
return 0;
}
因为父、子进程的fork()各自返回不同的ret,所以在执行if语句时会进入不同的分支

7841

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



