进程任务结构与初始化

转载 2012年03月25日 21:49:14

Linux系统的线程实现非常特别:他对线程和进程并不特别区分。对linux而言,线程只不过是一种特殊的进程罢了,后面我们会看到,他们都通过do_fork函数创建,只是传入的参数不一样而已。线程创建时,会共享内核资源。

       在内核中,各个进程的task_struct存放在他们内核栈的尾端。这样做是为了让那些像x86那些寄存器较少的硬件体系结构只要通过栈指针就能计算出他的位置而避免额外的寄存器专门记录。寄存器较弱的体系结构不是引入thread_info结构的唯一原因。这个新建的结构使在汇编代码中计算其偏移变量非常容易。由于现在用slab分配器动态生成task_struct,所以只需要在栈底(对于向下增长的栈来说)或栈顶(对于向上增长的栈来说)创建一个新的结构struct thread_info。

  1. <span style="font-size:18px;">union thread_union {/*大小为8k*/  
  2.     struct thread_info thread_info;  
  3.     unsigned long stack[THREAD_SIZE/sizeof(long)];/*大小为8k*/  
  4. };</span>  

从这个联合体中可以看到,thread_info结构体和栈存放在两个页面中,而栈的大小正好是两个页面,这也论证了上面所说的。

下面来看看如何获得当前进程的指针

  1. <span style="font-size:18px;">#define current get_current()  
  2.   
  3. #define get_current() (current_thread_info()->task)  
  4.   
  5. static inline struct thread_info *current_thread_info(void)  
  6. {  
  7.     struct thread_info *ti;  
  8.     /*函数percpu_read_stable(kernel_stack)取得相应当前cpu上  thread_info所在的地址,返回值是整数。*/  
  9.     ti = (void *)(percpu_read_stable(kernel_stack) +  
  10.               KERNEL_STACK_OFFSET - THREAD_SIZE);  
  11.     return ti;  
  12. }</span>  

其中kernel_stack为内核per CPU变量

  1. <span style="font-size:18px;">DEFINE_PER_CPU(unsigned long, kernel_stack) =  
  2.     (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;</span><span style="font-family: Arial, Verdana, sans-serif; font-size: 18px; white-space: normal; background-color: rgb(255, 255, 255); "> </span>  

      thread_union是一个联合体,里面定义了thread_info结构和堆栈结构,THREAD_SIZE在32位平台上一般定义为4K,所以stack的大小其实就是4KB,这就是初始任务在核心里所拥有的所有空间,除去thread_info和KERNEL_STACK_OFFSET占用的空间后,就是任务在核心里实际拥有堆栈的大小。KERNEL_STACK_OFFSET定义为5*8,由于是unsigned long,所以堆栈底部以上还有5*8*4B=200B的空间用来存放程序运行时相关的环境参数。

      内核栈采用每个CPU数据(per_cpu_data)的概念,在每一个处理器中各自维护一个以前在多个CPU之间进行共享的数据,如当前运行的任务结构体,以前就是在多个CPU之间共享的。

关于内核进程初始化

首先我们要知道linux中第一个进程时内核进程,pid为0,他是所有进程的父进程。这个进程也叫swapper,或者idle。这个进程时静态初始化的,定义为:

  1. <span style="font-size:18px;">/* 
  2.  * Initial thread structure. 
  3.  * 
  4.  * We need to make sure that this is 8192-byte aligned due to the 
  5.  * way process stacks are handled. This is done by making sure 
  6.  * the linker maps this in the .text segment right after head.S, 
  7.  * and making head.S ensure the proper alignment. 
  8.  * 
  9.  * The things we do for performance.. 
  10.  */  
  11. union thread_union init_thread_union __init_task_data =  
  12.     { INIT_THREAD_INFO(init_task) };  
  13.   
  14. /* Attach to the init_task data structure for proper alignment */  
  15. #define __init_task_data __attribute__((__section__(".data.init_task")))</span>  

       这个进程主要用途就是保证至少会有一个进程还在运行,也就是说当没有进程运行的情况下,它是最后的那个进程,就是swaaper 进程.init进程就是由它派生出来的。

        然后来看对应的初始化,在header32.s中,这里是将init_thread_union的地址加上THREAD_SIZE(栈的大小)装载进esp,然后__BOOT_DS装载进ss32x86默认栈的大小为8k,因此一开始esp的值就是init_thread_union的地址+栈的大小。

  1. <span style="font-size:18px;">/* Set up the stack pointer */  
  2. lss stack_start,%esp  
  3.   
  4. .data  
  5. ENTRY(stack_start)  
  6.     .long init_thread_union+THREAD_SIZE  
  7.     .long __BOOT_DS</span>  

参考资料

http://www.cnblogs.com/justinzhang/archive/2011/07/18/2109923.html

http://www.pagefault.info/?p=36

linux内核设计与实现,深入理解linux内核

相关文章推荐

进程任务结构与初始化

Linux系统的线程实现非常特别:他对线程和进程并不特别区分。对linux而言,线程只不过是一种特殊的进程罢了,后面我们会看到,他们都通过do_fork函数创建,只是传入的参数不一样而已。线程创建时,...

linux内核--进程任务结构化与初始化

Linux系统的线程实现非常特别:他对线程和进程并不特别区分。对linux而言,线程只不过是一种特殊的进程罢了,后面我们会看到,他们都通过do_fork函数创建,只是传入的参数不一样而已。线程创建时,...

加载内核模块,实现新的系统调用:遍历系统当前所有进程的任务描述符,并将pid组织成树状结构显示

在Linux内核中增加一个系统调用,并编写对应的linux应用程序。利用该系统调用能够遍历系统当前所有进程的任务描述符,并按进程父子关系将这些描述符所对应的进程id(PID)组织成树形结构显示。

OSTaskStkInit():任务堆栈结构的初始化

转载请注明出处:http://dreamlcr.cublog.cn/ ---------------------------------------------------- OSTask...

每日一C-- 信号量结构体 利用信号实现进程间通信 初始化调用杀死

The sigaction structure is defined as something like: struct sigaction { vo...

任务管理器进程简介

PostgreSQL启动过程中的那些事七:初始化共享内存和信号二十:shmem中初始化堆同步扫描、pg子进程相关结构

这一节pg初始化堆扫描同步支持用到的相关结构。        堆扫描同步是当多个进程在同一个表上做顺序扫描(sequential scan),pg尝试保持他们同步以减少整体I/O需求。这个目标是读每...

MFC关闭任务管理器进程

  • 2016-12-14 14:37
  • 23.68MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)