Linux内核中存在process,thread,和light thread三种形式的“进程”,light thread是前两者的互补。
老版本的内核采用全局静态变量current来区分正在运行的进程,现在的内核则是将进程描述符与stack合并:
union thread_union {
struct thread_info thread_info;
unsigned long stack[2048]; /* 1024 for 4KB stacks */
};
内核使用alloc_thread_info 和 free_thread_info 宏来分配和释放存放进程(线程)信息数据结构和堆栈的内存区。
如果thread_union结构是8 KB内核mask掉esp的低13位来得到thread_info structure的基址; 如果是4KB则mask掉12位.这些通过current_thread_info( )函数完成, 产生的汇编代码与一下类似:
movl $0xffffe000,%ecx /* or 0xfffff000 for 4KB stacks */
andl %esp,%ecx
movl %ecx,p
执行这三条指令之后p存用目前运行在cpu上的进程执行这段代码的tHRead_info structure的指针。
大部分情况下内核需要的是进程描述符而不是thread_info structure的结构指针。内核通过轰 current来的到运行在cpu上的进程的进程描述符,它等同于current_thread_info( )->task产生的汇编代码与一下类似:
movl $0xffffe000,%ecx /* or 0xfffff000 for 4KB stacks */
andl %esp,%ecx
movl (%ecx),p
因为task域位于thread_info struct结构的0偏移地址处, 执行这段代码后p就指向了当前cpu运行进程的得到进程描述符。
current宏经常作为内核代码的前缀来访问进程描述符,例如 current->pid返回当前cpu上正在运行的进程的id。
关于Linux内核中大量使用的链表:
对一个操作系统来说,链表作为基本的数据结构是绝对不会少的,对于linux更是如此,无论是在内存管理,定时器,进程管理还是在驱动程序的编写中链表大量存在,双向链表最为好用,Linux为开发者提供了相应的宏来完成创建、释放链表、上溯链表owner等等功能,从而提高了效率。注意:linux中的这种链表结点叫做list_head,linux中这种双向链表的使用并不是用pre、next指针指向它的前一个和后一个结点的整个数据结构,而仅仅是指向其下一个结点的对应的list head结构,要访问其所指向的整个数据结构,是通过内核提供的特有的宏(类似于上溯到其owner的宏)来访问的。其实list head可以被看作是被嵌入在特定数据结构中的。
进程链表:
每个task_struct结构都包括一个list_head域 它的pre和next分别指向前一个和后一个task_struct结构。这个进程链表的表头是init_task的task描述符;也就是所谓的0号task或者叫做wrapper(就是那个idle)它的pre指向新插入的进程描述符的list_head。SET_LINKS和REMOVE_LINKS宏用来插入和善除尽程度列中的进程描述符。这些宏的操作也会考虑到进程间的关系。
关于运行队列:
用来加快task调度的方法的一种是通过将运行队列中的task划分成多个运行队列链表,每一个队列有一个task优先级。每一个task_struct描述符结构包括一个list_head类型的run_list成员。如果task具有优先级k,那么就把整个task插入到k优先级的运行队列中。这是一个通过增加数据结构负载性来提高运行效率的典型例子。
像我们看到的一样,内核需要一个复杂的数据结构来保存进程运行队列的数据,但是, 主要的数据结构是由一运行队列中的进程描述符。所有的这些链表都由prio_array_t数据结构实现。
Type Field Description
int nr_active 链入入链表的进程描述符数目
unsigned long [5] bitmap 优先级映射表,list不为空对应的一位置1
struct list_head [140] queue 140个链表的表头
enqueue_task(p,array)函数向运行队列承认一个进程描述符,代码本质上类似于:
list_add_tail(&p->run_list, &array->queue[p->prio]);
__set_bit(p->prio, array->bitmap);
array->nr_active++;
p->array = array;
进程间关系:
real_parent 指向创建进程p的进程描述符,或是指向1号进程号的进程描述符(父进程不存在后会被作为1好进程的子进程)
parent 当前的父进程。
children 进程P窗间的所有子进程的链表头。
sibling 拥有相同父进程的兄弟进程。
除此之外还存在其他的进程间关系:一个进程可以是一个进程组伙食一个登录会话的头,它可以作为一个领导进程来跟踪组中的其它进程。
PID hash表:
在许多情况下进程必须能够能通过PID来访问进程描述符。一个近程可以发送kill()系统调用而将令一个进程的pid作为参数传送。内核通过pid来找到进程描述符,并找到其挂起状态数据。
扫描进程列表查看pid域可以实现,但是效率低。linux通过四个hash表来加速查找,由于进程描述符包括代表不同类型的pid,而不同pid要求有自己的hash查找表,所以会引入四个hash表。
分享到:
相关推荐
总结来说,"Reading-and-comprehense-linux-Kernel-network-protocol-stack-master.7z"提供的资源是一个宝贵的资料库,对于希望深入了解Linux TCP/IP协议栈的开发者来说,这是一份不可或缺的学习材料。通过系统地...
`kernel-ml-aufs-devel-3.10.5-3.el6.x86_64.rpm` 和 `kernel-ml-aufs-3.10.5-3.el6.x86_64.rpm` 是两个RPM(Red Hat Package Manager)文件,它们是用于CentOS或RHEL(Red Hat Enterprise Linux)系统的软件包。...
将下载完的System32/api-ms-win-downlevel-kernel32-l2-1-0.dll 以及SysWOW64/api-ms-win-downlevel-kernel32-l2-1-0.dll解压到c:/Windows下
Linux Kernel 学习笔记 Linux Kernel 是 Linux 操作系统的核心组件,负责管理硬件资源、提供系统服务和执行系统调用。以下是 Linux Kernel 的学习笔记,涵盖了存储器寻址、设备驱动程序开发、字符设备驱动程序、PCI...
主要用于windows系统提示没有对应的api-ms-win-downlevel-kernel32-l2-1-0.dll动态库时导致的一系列报错问题。下载解压后,放到对应目录下:C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\api-ms-win-...
这个压缩包“Reading-and-comprehense-linux-Kernel-network-protocol-stack_y123456yz.tar.gz”提供了一份详细的源码分析,对于学习和理解Linux内核如何处理网络数据包,特别是对C语言编程有一定基础的人来说,是一...
kernel-3.10.0-327.el7.x86_64.rpm kernel-debug-3.10.0-327.el7.x86_64.rpm kernel-debug-devel-3.10.0-327.el7.x86_64.rpm kernel-devel-3.10.0-327.el7.x86_64.rpm kernel-headers-3.10.0-327.el7.x86_64.rpm ...
WSL2 Linux 6.6内核完整包
3、[root@centos kl]# rpm -ivh kernel-ml-tools-libs-devel-5.18.10- 1.el7.elrepo.x86_64.rpm --force --nodeps 4、[root@centos kl]# rpm -ivh kernel-ml-5.18.10-1.el7.elrepo.x86_64.rpm --force -- nodeps 5、...
WSL2-Linux-Kernel-linux-msft-wsl-5.15.133.1.zip
Red_Hat_Enterprise_Linux-7-Kernel_Administration_Guide-en-US
kernel-headers-3.10.0-957.el7.x86_64.rpm kernel-devel-3.10.0-957
`kernel-devel`包对于Linux开发者来说至关重要,它为构建针对特定内核版本的模块或驱动程序提供了必要的头文件和符号链接。本文将深入探讨`kernel-devel-3.10.0-1160.el7.x86_64.rpm`及其相关版本的细节,并提供下载...
标题“kernel-headers-3.10.0-957.el7.x86_64”指的是Linux内核头文件的一个特定版本,用于RPM(Red Hat Package Manager)包管理系统的环境。在这个案例中,它是针对Linux内核版本3.10.0-957,适配于EL7...
《深入理解Linux内核开发与优化:以kernel-headers-3.10.0-1160.zip为例》 在Linux系统的世界里,内核是操作系统的核心,它负责管理和调度系统的硬件资源,为上层应用程序提供服务。本文将围绕"kernel-headers-...
Linux注释内核
Linux kernel-2.6.38.1-i686.cfg
4. Linux内核版本发布说明:针对Linux内核版本5.x的发布说明,它提供了关于内核的详尽信息,解释了如何安装内核,以及如果出现问题应该如何处理。 5. Linux内核是什么:Linux是Unix操作系统的一个克隆版本,由Linus...
kernel-debuginfo-common-x86_64-2.6.32-358.el6.x86_64.rpm linux core crash debuginfo