Linux C-学习笔记(二)

为熟悉对Linux C的基本操作,阅读书籍《Linux C编程从入门到实践-程国刚等》与《Linux C从入门到精通-明日科技》,此为学习笔记。(四到六章)

4. Linux 的进程

进程 (process) 是多任务操作系统的一个概念。其通常被定义为程序执行时的一个实例,是可以分配给处理器并且交由处理器执行的一个实体。

引入:支持多任务的操作系统在执行多个任务的时候需要共享系统资源,这导致不同的任务之间存在相互制约的关系,程序的执行表现出间断性特征。这些特征是在程序执行过程中发生的,是动态过程,而C语言程序编译连接后生成的可执行文件是一组指令的集合,是静态的,无法描述程序在内存中并发的执行情况,故引入进程。

!!“进程”和“线程”

4.1 进程基础

4.1.1 进程的特点

进程由程序、数据和进程控制块组成。多个不同的进程可包含相同的可执行文件,一个可执行文件在不同数据集里构成不同的进程,得到不同结果。

  • 动态性:进程实质是一个可执行文件(程序)在多任务操作系统中的一次执行过程,动态产生和消亡。
  • 并发性:人和进程都可以同其他进程一起并发执行。
  • 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
  • 异步性:由于进程之间相互制约,一个进程的操作步骤不一定连续执行。

Linux内核管理着多个用户的请求和多个任务,每个任务或请求对应着一个进程。

4.1.2 进程的四要素

  • 有一段代码供进程运行
  • 有专用的系统堆栈空间
  • 有一个由 task_struck 结构来实现进程控制块
  • 有独立的存储空间

4.1.3 进程的标识方法

两种方式:进程描述符的地址,进程标识符。(这两都是唯一的)

(1) 进程描述符

为对进程进行管理,Linux内核必须了解每个进程当前的执行状态(包括 进程优先级、进程运行状态和进程分配的地址空间等),用一个 task_struct 结构体 进程描述符 (processor descriptor) 来存放这些信息。

Linux内核提供一个数组 task 用于存放进程描述符,其包含指向系统中所有 task_struct 结构的指针。这意味着系统中最大进程数受数组 task 数组大小的限制,缺省值一般为 512。
以下是一个进程描述符的主要结构:

struct task_struct	{
volatile long state;
//进程的运行状态:-1:不可运行; 0:可运行; >0:已停止;
unsigned int flags;
// 进程当前状态标识:
// 0x00000002 表示进程正在被创建
// 0x00000004 表示进程正准备退出
// 0x00000040 表示此进程被 fork 出,但未执行 exec
// 0x00000400 表示此进程因其他进程发出相关信号而被 Kill
unsigned int rt_priority
// 进程优先级
struct list_head tasks;
struct mm_struct *mm;
int exit_state;
pid_t pid;
// 进程标识号
struct task_struct *real_parent;
// real_parent 为该进程的“亲生父亲”
struct task_struct *parent;
// real_parent 为该进程的父进程
struct task_struct children;
// 为该进程孩子的链表,可以得到所有子进程的进程描述符
struct task_struct sibling;
// 为该进程兄弟的链表,可以得到其父亲所有孩子的链表
struct task_struct *group_leader;
// 主进程的进程描述符
struct list_head thread_gruop;
// 进程中所有线程的链表
unsigned long timer_slack_ns;
unsigned long default_timer_slack_ns;
...
}
(2) 进程标识符(Processor ID, PID)

PID 是在当前Linux系统中唯一的非负整数,用于标识和对应唯一的进程。

PID 按顺序编号。通产说是前一个进程的进程标识符加一。PID可以重复使用,当一个进程被回收之后,过一段时间,该PID可以被再次使用。

Linux中有几个特殊标识符对应的进程:

  • PID0:对应交换进程 (swapper),其用于多进程的调用;
  • PID1:对应初始化进程 (init),在自举过程结束时由内核调用,其对应文件 /sbin/init, 负责Linux启动工作,该进程在系统运行过程不会终止。可以说系统中所有进程都由该进程衍生而来;
  • PID2:可能对应页守护进程 (pagedaemon),用于虚拟存储系统的分页操作。

查看系统中正在运行的进程以及相关信息:

ps-aux

//getpid系列函数获得当前进程的PID:
#include<sys/types.h>
#include<unistd.h>
pid_t_getpid(void)
pid_t_getppid(void)  // 获得当前调用进程的父进程

// getpid系列函数获得进程对应用户相关信息:
uid_t_getuid(void);   // user id
uid_t_geteuid(void);  // efficient user id 
uid_t_getgid(void);	  // group id
uid_t_geteuid(void);  // efficient group id

4.1.4 进程的关系和分类

Linux系统中所有进程相互联系,程序创建的进程之间有 父/子关系,自进程之间有兄弟关系。
在这里插入图片描述

  • p_pptr: 父进程 (parent),其指向进程的父进程;
  • p_cptr: 子进程 (child);
  • p_ystr: 弟进程 (younger sibling),指向在本进程创建之由父进程创建的进程;
  • p_ostr: 兄进程 (older sibling),指向在本进程创建之由父进程创建的进程;

Linux操作系统通常包含三种不同类型的进程:

  • 交互进程:一个由 shell 启动的进程,可以在前台、后台运行;
  • 批处理进程:这种进程和终端没有关系,是一个进程序列;
  • 守护进程: 系统启动时启动的进程,并在后台运行。

4.1.5 进程的状态

  • 可运行状态 (TASK_RUNNING),占用处理器执行或准备执行;
  • 可中断的等待状态 (TASK_INTERRUPTIBLE),进程被挂起或睡眠,当某条件为真时才退出该等待状态进入RUNNING,这些条件包括:硬件中断,进程正在等待的资源被释放,传递一个信号等;
  • 不可中断的等待状态 (TASK_UNINTERRUPTIBLE): 类似上一个,区别在当收到信号的时候不可退出该等待状态;
  • 暂停状态 (TASK_STOPPING):通常说进程收到信号 SIGSTOP, SIGTTIN, SIGTTOU后,进入暂停状态;
  • 僵尸状态 (RASK_ZOMBIE): 进程执行已被终止,但父进程还未使用 wait 调用已返回的相关信息,此时内核不可以丢弃该进程的数据,因为父进程可能还需用到这些数据。

进程在这几个状态之间的切换,对用户来说是透明的。该切换过程也称为**“进程的调度”**。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值