进程是操作系统分配资源的最小单位,linux系统上的进程是如何表示和操作的呢?
所有设备都只能直接和内存打交道。
这样做的好处是将需要等待的数据存储到内存中,读取数据就是内存的速度,提升了计算机整体的运行速度。
即使是些简单操作,都用到每一部分。
QQ中传递文件:输入:磁盘、输出:网卡 、输入:网卡、输出:磁盘
QQ中聊天:输入:键盘、输出:网卡 、输入:网卡、输出:显示器
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。
操作系统包括:
硬件部分遵守冯诺依曼体系
OS不信任任何用户,任何对系统硬件或者软件访问,都必须通过OS的手
计算机体系是一个层状结构,任何访问硬件或者软件的行为,都必须通过OS接口,贯穿OS进行访问
库函数:语言或者第三方库(第一方:系统的、第二方:自己的,其余是第三方的)给我们提供的接口
系统调用:OS提供的接口
总结:
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
操作系统:内核关于进程的数据结构(PCB) + 当前进程的代码和数据
描述进程-PCB
- 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。称之为PCB(process control block),Linux操作系统下的PCB是: task_struct 。task_struct是PCB的一种
- 在Linux中描述进程的结构体叫做task_struct。
- task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
task_ struct内容分类
- 标示符: 描述本进程的唯一标示符,用来区别其他进程。
- 状态: 任务状态,退出代码,退出信号等。
- 优先级: 相对于其他进程的优先级。
- 程序计数器: 程序中即将被执行的下一条指令的地址。
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- 上下文数据: 进程执行时处理器的寄存器中的数据
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
- 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
- 其他信息
ps axj
//查看进程
ps axj | head -1 && ps axj | grep "test"
//带标题栏和过滤带有“test"的进程
top
//查看进程占资源情况
ls /proc
ls /porc/xxx -al
//这些目录保存了当前系统中运行的所有进程的信息
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
- R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
- D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
- Z(zombie)-僵尸进程:
父进程先退出,子进程就称之为“孤儿进程”
进程的优先级:
- cpu资源分配的先后顺序,就是指进程的优先权(priority)。
- 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
- 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
命令行中一般有两个变量:本地变量、环境变量
本地变量:只能够在当前shell命令行解释器内被访问,不可以被子进程继承
环境变量:具有”全局属性“ 可以被子进程继承
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
#include
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}
#include
#include
#include
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0)
{
perror("fork");
return 0;
}
else if(id == 0)
{
//child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
g_val=100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
else
{
//parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8
父子进程中的g_val的地址竟然是一样的
地址空间本质是进程看待内存的方式,是抽象出来的一个概念,内核struct mm_struct,这样的每一个进程,都认为自己独占系统内存资源
区域划分本质:将线性地址空间划分成为一个一个的area,[start,end]
虚拟地址本质:在[start,end] 之间的各个地址叫做虚拟地址
进程管理是操作系统的重要作用之一。
强烈的信仰会赢取坚强的人,然后又使他们更坚强。——华特贝基霍