[Linux驱动入门]进程管理
来源:互联网 发布:in Linux system 编辑:程序博客网 时间:2024/06/10 22:22
第二章 进程管理
2.1 进程调度
Linux提供抢占式多任务模式,进程在被抢占之前能够运行的时间叫进程的时间片,Linux独一无二的公平调度程序本身并没有采用时间片来达到公平调度。
进程分为I/O消耗型和处理器消耗型。前者指进程的大部分时间用来提交I/O请求或是等待I/O请求的;后者是指进程把事件大多数用在执行代码上。Linux更倾向于优先调度I/O消耗型进程。
Linux采用两种不同的优先级范围:第一种是nice值,越大的nice值意味着更低的优先级;第二种是实时优先级,其值可以配置,越高的实时优先级数值意味着进程优先级越高。
2.2 Linux调度的实现
(1)时间记账
(2)进程选择
(3)调度器入口
(4)睡眠和唤醒
2.3 抢占和上下文切换
上下文切换是从一个可执行进程切换到另一个可执行进程。Schedule函数主要完成两个工作:其一,把虚拟内存从上一个进程映射切换到新进程中;其二,从上一个进程的处理器状态切换到新进程的处理器状态。
内核中need_resched标志表明是否需要重新执行一次调度,该标志对于内核来讲是一个信息,它表示有其他进程应当被运行了,要尽快调用调度程序。
用户抢占:内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule函数被调用,此时会发生用户抢占。用户抢占一般在如下情况下发生:其一,从系统调用返回用户空间时;其二,从中断处理程序返回用户空间时。
内核抢占:内核可以在任何时候抢占正在执行的任务。内核抢占一般在如下情况下发生:
(1)中断处理程序正在执行,且返回用户空间之前;
(2)内核代码再一次具有可抢占性的时候;
(3)如果内核中的任务显式地调用schedule函数;
(4)如果内核中的任务阻塞。
2.4 进程概念
进程是正在执行的程序代码的实时结果,是处于执行期的程序以及相关的资源的总称。线程是在进程中活动的对象,内核调度的对象是线程,而不是进程。
进程提供两种虚拟机制——虚拟处理器和虚拟内存。线程之间可以共享内存,但每个都拥有各自的虚拟处理器。
进程五种状态标志:TASK_RUNNING,TASK_INTERRUPTIBLE,TASK_UN INTERRUPTIBLE,TASK_TRACED,TASK_STOPPPED.
2.5 进程上下文
程序在用户空间执行时,当一个程序执行了一个系统调用或者触发了某个异常,它就陷入内核空间,称为内核“代表进程执行”并处于进程上下文中。
2.6 进程与线程的创建
从现有内核线程中创建一个新的内核线程有两种方法:
(1)利用kthread_creat()函数创建,并用wake_up_process()唤醒;
(2)直接执行kthread_run().
内核线程启动之后就一直运行直到调用do_exit()退出,或者内核的其他部分调用kthread_stop()退出。
2.7 孤儿进程
如果父进程在子进程之前退出,必须有一个机制来保证子进程能找到一个新父亲,否则这些孤儿进程就会在退出时永远处于僵死状态,白白耗费内存。
2.8 系统调用
系统调用是用户空间访问内核的唯一手段,除异常和陷入外,它们是内核唯一的合法入口。
定义一个系统调用:
asmlinkage long sys_test(void)
内核在执行系统调用的时候处于进程上下文,在进程上下文中,内核可以休眠,并且可以被抢占。系统调用返回的时候,控制权仍在system_call中,它最终负责切换到用户空间,并让用户继续执行下去。
2.9 内核设计系统调用
主要完成系统调用函数编写,系统调用号,系统调用表的填写。
步骤1:在“/include/linux/syscalls.h”中增加要添加的系统调用的声明。
asmlinkage long sys_test(void);
步骤2:在“/arch/arm/include/asm/unistd.h”
#define _NR_test(_NR_SYSCALL_BASE+361)
步骤3:在“/kernel/sys.c”中实现系统调用函数。
asmlinkage long sys_test(void)
{
printk(“pid: %d,this is test call.\n”,current->pid);
return 0;
}
步骤4:在“/arch/arm/kernek/calls.S”中加入系统调用表的初始化部分
/* 361 */ CALL(sys_test)
步骤5:生成内核镜像。应用层测试程序。
#include <Linux/unisted.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int i = 10;
i = syscall(361);
printf(“after syscall : i = %d\n”,i);
return 0;
}
测试结果:
pid: 859,this is test call.
after syscall:i = 0
- [Linux驱动入门]进程管理
- linux驱动开发-进程管理
- [Linux驱动入门]内存管理
- Linux操作系统入门-进程管理
- Linux 入门笔记6. 进程管理入门
- Linux内核驱动学习(五)----进程管理子系统
- Linux内核驱动学习(五)----进程管理子系统
- Supervisor-进程管理入门
- Linux入门四:进程及任务管理命令
- 【Linux驱动】内存管理
- 【Linux开发】linux设备驱动归纳总结(四):1.进程管理的相关概念
- linux驱动入门
- Linux驱动入门
- Linux驱动入门
- Linux驱动入门
- Linux驱动入门
- Linux驱动入门转
- Linux驱动入门收藏
- Java 第12章典型例子
- vi笔记3——vi之快速移动
- ros by example2 学习过程记录-0
- printf相关函数详解
- 将Logger的数据导入到数据库详解
- [Linux驱动入门]进程管理
- Java 第13章典型例子(石头剪刀布)
- Redis基础
- const的常见使用说明,用法
- C++ string类和字符串的访问和拼接操作
- 进程与线程的区别
- 解决git push 时每次都需要输入用户名和密码
- sql 多表插入和时区
- Java中的String类(不可变类)变还是不变?