linux进程管理与调度(一)
来源:互联网 发布:mac air怎么有两个账户 编辑:程序博客网 时间:2024/06/05 05:56
转载请标明出处floater的csdn blog,http://blog.csdn.net/flaoter
进程的管理与调度是所有操作系统的核心功能。从内核的角度来看,进程是内核分配资源(CPU,Memory)的重要单元,是计算机用来管理这些资源的一种抽象。从本节开始,将对linux内核的进程管理与调度子系统进行分析,其中使用的内核版本是4.4。
1 进程描述
在linux内核中,每一个进程唯一对应一个struct task_struct结构体,内核通过这些task_struct的管理实现对进程的管理。此数据结构定义在./include/linux/sched.h中,结构太过庞大,下面作为实例只列出了前面几行。
struct task_struct { volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ void *stack; atomic_t usage; unsigned int flags; /* per process flags, defined below */ unsigned int ptrace;#ifdef CONFIG_SMP struct llist_node wake_entry; int on_cpu; unsigned int wakee_flips; unsigned long wakee_flip_decay_ts; struct task_struct *last_wakee; int wake_cpu;#endif int on_rq;....}
按照结构成员的用途,大体上分成了如下的类别,
(1) 基本信息。comm, pid, tgid, uid, gid, stack, on_cpu, on_rq, in_execve, in_iowait…
(2) 进程关系。real_parent, children, sibling…
(3) 状态相关。state, exit_state, exit_code…
(4) 使用内存。mm, active_mm, min_flt, maj_flt…
(5) 调度相关。prio, static_prio, normal_prio, rt_prio, sched_class, se, policy…
(6) 事件相关。utime, stime, start_time, real_start_time…
(7) 信号相关。signal, sighand, blocked, real_blocked, pending…
(8)文件系统。fs, files, nameidata…
(9) Misc
2 进程状态
进程的状态定义如下所示,
#define TASK_RUNNING 0 //R态,进程正在运行或在rq中等待运行#define TASK_INTERRUPTIBLE 1 //S态,阻塞等待资源或者信号#define TASK_UNINTERRUPTIBLE 2 //D态,阻塞等待资源#define __TASK_STOPPED 4 //暂停状态#define __TASK_TRACED 8 //跟踪状态/* in tsk->exit_state */#define EXIT_DEAD 16#define EXIT_ZOMBIE 32#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)/* in tsk->state again */#define TASK_DEAD 64#define TASK_WAKEKILL 128#define TASK_WAKING 256#define TASK_PARKED 512#define TASK_NOLOAD 1024#define TASK_STATE_MAX 2048
状态转换的状态机如图所示,
3 进程初始化
进程的初始化是在start_kernel中的reset_init中实现的,创建了两个进程init和kthreadd。
kernel_thread(kernel_init, NULL, CLONE_FS); //init进程创建pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); //kthread内核线程创建
创建的init进程再通过解析init.rc等文件进行用户进程的创建。
static int __ref kernel_init(void *unused){... if (!try_to_run_init_process("/sbin/init") || !try_to_run_init_process("/etc/init") || !try_to_run_init_process("/bin/init") || !try_to_run_init_process("/bin/sh")) //执行init程序,parse init.rc,创建子进程 return 0;...}
init进程与用户进程的关系如下:
init-+-adbd-+-sh—busybox
| -4*[{adbd}]
-{Binder_2}
|-cndaemon
|-cp_diskserver---{cp_diskserver}
|-debuggerd
|-debuggerd64
|-drmserver-+-{Binder_1}
|
|-gatekeeperd
|-gnss_download—2*[{gnss_download}]
|-gpsd—2*[{gpsd}]
|-healthd
|-installd
|-keystore
|-lmfs
|-lmkd
|-logd-+-{logd.auditd}
| |-{logd.control}
| |-{logd.daemon}
| |-5*[{logd.reader.per}]
| |-{logd.reader}
| `-{logd.writer}
|-main-+-.quicksearchbox-+-{ApplicationsPro}
| | |-{Binder_1}
| | |-{Binder_2}
| | |-{FinalizerDaemon}
| | |-{FinalizerWatchd}
| | |-{HeapTaskDaemon}
…
创建的kthreadd内核线程通过遍历kthread_create_list创建内核线程。
int kthreadd(void *unused){... set_task_comm(tsk, "kthreadd"); for (;;) {... spin_lock(&kthread_create_lock); while (!list_empty(&kthread_create_list)) { struct kthread_create_info *create; create = list_entry(kthread_create_list.next, struct kthread_create_info, list); //遍历kthread_create_list,创建子线程 list_del_init(&create->list); spin_unlock(&kthread_create_lock); create_kthread(create); spin_lock(&kthread_create_lock); } spin_unlock(&kthread_create_lock); } return 0;}
kthreadd与内核线程的关系如下:
kthreadd-+-VserTestWq
|-adaptive_ts_wor
|-agdsp_access
|-ata_sff
|-aud_sblock-1-3
|-aud_sblock-1-4
|-binder
|-bioset
|-bm_perf
|-carveout_camera
|-carveout_fb
|-carveout_mm
|-carveout_overla
|-cfg80211
|-cfinteractive
|-compr drain
|-compr monitor
|-crypto
|-deferwq
|-devfreq_wq
|-dhd_dpc
|-dhd_rxf
|-dhd_watchdog_th
…
4 进程创建
常用的进程创建方法如下:
fork—————–用户进程
pthread_create—- 用户线程
kthread_create —-内核线程
do_fork
5 thread_info与内核栈
thread_info保存了特定体系结构的汇编代码段需要访问的那部分进程的数据。内核栈供用户进程的内核代码或内核线程使用。arm 32bit 处理器thread_info和内核栈task->stack合用2页内存空间。
union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)];};
常用的current指针指向了当前的thread_info的task成员。
#define get_current() (current_thread_info()->task)#define current get_current()
static inline struct thread_info *current_thread_info(void){ return (struct thread_info *) (current_stack_pointer & ~(THREAD_SIZE - 1));}
current_thread_info就是当前sp屏蔽掉低12位。
- linux进程管理与调度(一)
- Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)
- Linux进程的管理与调度(一)--- Linux进程描述符task_struct结构体详解
- linux进程调度与管理(二)
- linux进程调度与管理(三)
- linux进程管理与调度
- linux进程管理与调度
- Linux进程管理与调度
- linux进程管理与调度
- linux进程管理与调度
- linux进程管理与调度
- linux进程管理与调度
- Linux 进程管理(一) 进程调度
- Linux进程调度器概述--Linux进程的管理与调度(十五)
- Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)
- Linux进程调度器的设计--Linux进程的管理与调度(十七)
- Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)
- linux进程管理之调度与切换
- Oracle存储过程
- LeetCode-257. Binary Tree Paths (Java)
- 非阻塞式connect
- HTML学习笔记
- JavaScript 引擎的LHS查询和RHS查询
- linux进程管理与调度(一)
- 一文搞懂傅里叶变换
- 实现类似“另存为”的功能
- 静态链接 和 动态链接
- 什么是WebService?
- 以太坊下链优化方案的探讨
- java聊天程序 基于socket 包含MySQL
- ArrayList
- 一种毫无节操的机制---预解释