您的位置:首页 > 理论基础 > 数据结构算法

内存管理器(九)内核内存管理–进程相关数据结构

2015-11-04 14:59 417 查看


内存管理器(九)内核内存管理–进程相关数据结构


前言

前面的几篇博文都是在学习用户态内存管理,malloc与free 也研究了Glibc 的内存管理函数的实现,本来想点到位置,但是觉得还是太浅了,不够深入,遂决定,继续挖掘下去(读破万卷始见金嘛)。所以再次修改学习路线,希望最后能做出来一切实可用的东西。

毕竟本科学习阶段主要还是在于掌握原理上的东西,真的很难做出什么有实际价值的东西,但是持续的造轮子也有助于我们学习和锻炼。

基本上下来就按照两步走的策略。

第一步:

学习目标与目的:以学习kernel内存管理的思想为核心,主要是学习其数据结构设计和算法思想。

实践方式:主要就是写内核模块看看在程序运行时,内存到底发生了什么。

第二步:

主要以实践为主,准备做一个内存的监控与调整程序。但是细节与需求还没有具体设计。先完成第一步,在这个过程中总结思考吧。

基本定于这个月内能完成第一步最好,但是最好能够完成吧,然而22号还有出去金工实习,,,,


__start

废话不多说,开始说正事。

既然说到进程,就必须的说task_struct .但是我想先说下pid_t 这个类型,就先说下它吧,之前对它我还是有点疑惑的。本来还以为这是个什么结构体类型,今天正好看到源码就先说它吧。

< typedef int __kernel_pid_t; typedef __kernel_pid_t pid_t; 由此看出,pid_t 就是整形。其实书上都写了,但是如果不是我亲眼看到,怎么都不放心,强迫症没办法。。 >

现在正式来说task_struct

在我的4.0.4 内核源码中仅仅task_struct 这个进程描述符就有435行,所以我就部全部列举了,下面简要说几个重要的
struct task_struct{


volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

//进程的状态,-1:不可运行 0:可运行 >0 :停止

void *stack; //栈

atomic_t usage;

unsigned int flags; /* per process flags, defined below */

//每进程标志

unsigned int ptrace;

unsigned lock_depth; /*大内核锁深度*/

int on_rq;

int prio, static_prio, normal_prio; //进程动态优先级,静态优先级,普通优先级

unsigned int rt_priority;

const struct sched_class *sched_class; //进程所有调用函数的集合

struct sched_entity se; //保存这进程的权重

struct sched_rt_entity rt;

pid_t pid; //进程ID

pid_t tgid;

struct task_struct __rcu *real_parent; /* real parent process */(在被调试情况下)

struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */

/*

* children/sibling forms the list of my natural children

*/

struct list_head children; /* list of my children *///子进程链表

struct list_head sibling; /* linkage in my parent’s children list */

//兄弟进程链表

struct task_struct *group_leader; /* threadgroup leader */

/*

* ptraced is the list of tasks this task is using ptrace on.

* This includes both natural children and PTRACE_ATTACH targets.

* p->ptrace_entry is p’s link on the p->parent->ptraced list.

*/

struct list_head ptraced; //调试使用

struct list_head ptrace_entry;

/* PID/PID hash table linkage. */ //进程描述符和哈希表存储

struct pid_link pids[PIDTYPE_MAX];

struct list_head thread_group;

struct list_head thread_node;

struct completion *vfork_done; /* for vfork() */

int __user *set_child_tid; /* CLONE_CHILD_SETTID */

int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */

cputime_t utime, stime, utimescaled, stimescaled; //和CPU时间相关的变量

cputime_t gtime;

struct rcu_head rcu;

unsigned long nvcsw, nivcsw; /* context switch counts */ //上下文切换次数

u64 start_time; /* monotonic time in nsec */

u64 real_start_time; /* boot based time in nsec */ //记录启动时间

/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */

unsigned long min_flt, maj_flt;

struct task_cputime cputime_expires;

struct list_head cpu_timers[3];

/* process credentials */

const struct cred __rcu *real_cred; /* objective and real subjective task

* credentials (COW) */

const struct cred __rcu *cred; /* effective (overridable) subjective task

* credentials (COW) */

char comm[TASK_COMM_LEN]; /* executable name excluding path 进程的名字

– access with [gs]et_task_comm (which lock

it with task_lock())

– initialized normally by setup_new_exec */

/* file system info */

int link_count, total_link_count;

/* ipc stuff */

struct sysv_sem sysvsem;

struct sysv_shm sysvshm;

/* filesystem information 文件系统信息*/

struct fs_struct *fs;

/* open file information */

struct files_struct *files;

/* namespaces 命名空间*/

struct nsproxy *nsproxy;

/* signal handlers 信号处理*/

struct signal_struct *signal;

struct sighand_struct *sighand;

sigset_t blocked, real_blocked;

sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */

struct sigpending pending;

unsigned long sas_ss_sp;

size_t sas_ss_size;

int (*notifier)(void *priv);

void *notifier_data;

sigset_t *notifier_mask;

struct callback_head *task_works;

struct audit_context *audit_context;

/*

* cache last used pipe for splice

*/

struct pipe_inode_info *splice_pipe; //管道相关

struct page_frag task_frag;

以上就是进程描述符的基本内容。

当然这些都是静态的内核代码,我们可以从/proc 中看到更多关于进程相关信息的东西,比如每一个进程都有资源限制,且限制是动态的,此时我们就去看/proc/self/limits .就可以看到进程的限制





 

这就是进程的限制参数了。


进程的类型

进程一般就两个类型:

1.fork 产生的子进程

2.exec 从一个可执行二进制文件加载另一个应用程序。

两者区别就不多说了 ,很简单。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: