进程相关概念及C程序的存储空间的分配

进程的基本概念

我们在编写完代码并运行起来时,在我们的磁盘中会形成一个可执行文件,当我们双击这个可执行文件时(程序时),这个程序会加载到内存中,而这个时候我们不能把它叫做程序了,应该叫做进程。

所以说,只要把程序(运行起来)加载到内存中,就称之为进程。

从上述中我们会发现进程和程序并不是一个概念,简而言之:

程序:静态的,磁盘中生成的pro文件,叫程序

进程:程序的一次运行活动(程序跑起来,系统中就会多一个进程)

进程的描述——PCB

PCB:进程控制块(结构体)

当一个程序加载到内存中,操作系统要为刚刚加载到内存的程序创建一个结构体(PCB),进程信息被放在这个结构体中(PCB),可以理解为PCB是进程的属性的集合。

linux操作系统下的PCB:task_struct

task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息

在进程执行时,任意时间内,进程对应的PCB都要以下内容:

标示符、状态、优先级 、程序计数器 、内存指针、上下文数据、I/O状态信息 、记账信息 、其他信息

进程相关概念及C程序的存储空间的分配_第1张图片

PCB通过双向链表相互连接,操作系统通过PCB,来找到进程。

进程相关概念及C程序的存储空间的分配_第2张图片

如何查看系统中有哪些进程

使用ps指令查看,在实际工作中,配合grep来查找程序中是否存在某一个进程。

ps命令:

通过ps aux | grep 文件名来找

其中getpid()是找进程的标示符,getppid()找父进程的标示符

ps命令的参数以及作用:

参数 作用
-a 显示所有进程(包括其他用户的进程)
-u 用户以及其他详细信息
-x 显示没有控制终端的进程

进程的状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面是kernel源代码里面的定义

/*
* 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):可执行状态

通过命令:ps aux,得到下面的如图红色框起来的表示该文件为可执行状态

进程相关概念及C程序的存储空间的分配_第3张图片

值得注意的是:进程中的R状态不代表正在运行,代表的可被调度,此运行相当于上面的就绪态。

操作系统会把进程中R状态的进程全放在调度队列中,方便调度。

进程相关概念及C程序的存储空间的分配_第4张图片

S (sleeping):睡眠状态

S状态是浅度睡眠,随时可以被唤醒,也可以被杀掉。

用代码创建一个睡眠状态的进程:

1)创建了一个可执行态进程

#include
#include
int main() 
{
    while(1);
	return 0;
}

2)创建休眠态进程

#include
#include
int main() 
{
    while(1)
    sleep(10);
	return 0;
}

D (disk sleep):磁盘休眠状态

可以表示为深度睡眠,该进程不会被杀掉,即使你是操作系统,除非我自动唤醒,才可以恢复。

T (stopped): 暂停状态

向进程发送SIGSTOP信号,该进程会响应该信号进入暂停状态, 向该进程发送SIGCONT信号,该进程会从暂停状态恢复到可执行状态。

X (dead) 死亡状态 & Z (zombie) 僵尸状态

死亡状态:进程被操作系统释放了或者自己退出了。

僵尸状态:一个处于僵尸状态的进程,会等待它的父进程或操作系统对它的信息进行读取,之后才会被释放。

进程的优先级

基本概念

cpu中的资源是有限的,不可能多个进程一起在CPU上运行,利用优先级把进程有效的先后排好,改善了系统的性能。

cpu资源分配的先后顺序,就是指进程的优先权(priority)

优先权高的有优先执行权。

查看系统进程

ps -l可以查看到进程的优先级

PRI:表示这个进程被执行的优先级,其值越小越早执行
NI:表示这个进程的nice值

PRI和NI

nice值表示进程可被执行的优先级的修正值。
PIR=PIR(old)+nice。
当nice为负值时,那么该进程的优先级值会变小,优先级会变高,进程越快被执行。

当然,nice也是有范围的,-20~19,一共40个级别。

环境变量

基本概念

环境变量(environment variables):一般是指在操作系统中用来指定操作系统运行环境的一些参数

先以windows为例来理解

我们咋windows双击软件就可以运行,不像linux需要打a.out,其实是我们再安装软件时,系统把软件的路径添加到了环境变量PATH中。

找到windows的环境变量:

打开控制面板——>点击“系统与安全”——>点击“查看计算机名称”——>找到高级系统设置,点击进去——>找到环境变量并点击进去

会得到下面这样一个页面

进程相关概念及C程序的存储空间的分配_第5张图片

我们咋windows双击软件就可以运行,其实是我们再安装软件时,系统把软件的路径添加到了环境变量PATH中。
所以说,安装软件相当于拷贝到PATH中。

我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但
是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

回到linux系统,如果我们想要查看环境变量,怎么办呢?

可以利用echo $name(name是指你要看的环境变量的名字)

常见的环境变量有PATH、HOME、SHELL

拿PATH来举例

PATH环境变量(指定命令的搜索路径)

在Linux中的一些指令是通过PATH环境变量来查找到指令的路径进而执行的。
ls指令和自己写的代码程序来比较
创建text.c文件

 #include

 int main()
 {
       printf("hello PATH\n");
       return 0; 
 }

这是因为在使用ls命令时,系统会通过PATH环境变量来查找ls,而a.out没办法通过PATH环境变量来找到,PATH环境变量中没有a.out的路径。

如何可以把自己写的文件可以像ls一样用呢?

把自己文件所在的路径添加到环境变量PATH中

通过export PATH=$PATH:a.out的所在的路径来

进程相关概念及C程序的存储空间的分配_第6张图片

剩下的HOME、SHELL环境变量,如果感兴趣的话,可以看下面这个博客,这里就不展开来说了

大佬博客:【Linux入门】进程概念(超详解,建议收藏)_linux进程-CSDN博客

C程序的存储空间的分配

C程序的存储空间是如何分配的?

大佬博客:堆和栈详解

程序运行时的内存分区主要分为BSS段、数据段、代码段、堆、栈

  • BSS段:Block Started by Symbol,一般是指存放程序中未初始化的全局变量的一块内存区域。BSS段属于静态内存分配。
  • 数据段:data segment,一般是指用来存放程序中已初始化的全局变量的一块内存区域。 static 意味着 在数据段中 存放变量,数据段属于静态内存分配。
  • 代码段:code segment/text segment,通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些 只读的常数变量 ,例如字符串常量等。程序段为程序代码在内存中的映射。一个程序可以在内存中有多个副本。
  • 堆:heap,堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)。
  • 栈:stack,栈又称堆栈,存放程序的局部变量(但不包括static声明的变量, static 意味着 在数据段中 存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的先进后出特点,所以栈特别方便用来保存/恢复调用现场。储动态内存分配,需要程序员手工分配,手工释放。

进程相关概念及C程序的存储空间的分配_第7张图片

 

你可能感兴趣的:(linux文件编程,进程,进程间通信,线程,网络编程,linux,运维,服务器)