当前位置: 首页 > news >正文

新闻类网站开发特点网站开发推荐

新闻类网站开发特点,网站开发推荐,wordpress文章图片加水印,郑州建设工程招标信息网内核线程为什么需要内核线程Linux内核可以看作一个服务进程(管理软硬件资源#xff0c;响应用户进程的种种合理以及不合理的请求)。 内核需要多个执行流并行#xff0c;为了防止可能的阻塞#xff0c;支持多线程是必要的。 内核线程就是内核的分身#xff0c;一个分身可以处…内核线程为什么需要内核线程Linux内核可以看作一个服务进程(管理软硬件资源响应用户进程的种种合理以及不合理的请求)。 内核需要多个执行流并行为了防止可能的阻塞支持多线程是必要的。 内核线程就是内核的分身一个分身可以处理一件特定事情。内核线程的调度由内核负责一个内核线程处于阻塞状态时不影响其他的内核线程因为其是调度的基本单位。 这与用户线程是不一样的。因为内核线程只运行在内核态 因此它只能使用大于PAGE_OFFSET传统的x86_32上是3G的地址空间。 内核线程概述内核线程是直接由内核本身启动的进程。内核线程实际上是将内核函数委托给独立的进程它与内核中的其他进程”并行”执行。内核线程经常被称之为内核守护进程。 他们执行下列任务 周期性地将修改的内存页与页来源块设备同步如果内存页很少使用则写入交换区管理延时动作, 如号进程接手内核进程的创建实现文件系统的事务日志 内核线程主要有两种类型 线程启动后一直等待直至内核请求线程执行某一特定操作。线程启动后按周期性间隔运行检测特定资源的使用在用量超出或低于预置的限制时采取行动。 内核线程由内核自身生成其特点在于 它们在CPU的管态执行而不是用户态。它们只可以访问虚拟地址空间的内核部分高于TASK_SIZE的所有地址但不能访问用户空间 内核线程的进程描述符task_structtask_struct进程描述符中包含两个跟进程地址空间相关的字段mm, active_mm struct task_struct {// ...struct mm_struct *mm;struct mm_struct *avtive_mm;//... }; 1234567 大多数计算机上系统的全部虚拟地址空间分为两个部分: 供用户态程序访问的虚拟地址空间和供内核访问的内核空间。每当内核执行上下文切换时, 虚拟地址空间的用户层部分都会切换, 以便当前运行的进程匹配, 而内核空间不会放生切换。 对于普通用户进程来说mm指向虚拟地址空间的用户空间部分而对于内核线程mm为NULL。 这位优化提供了一些余地, 可遵循所谓的惰性TLB处理(lazy TLB handing)。active_mm主要用于优化由于内核线程不与任何特定的用户层进程相关内核并不需要倒换虚拟地址空间的用户层部分保留旧设置即可。由于内核线程之前可能是任何用户层进程在执行故用户空间部分的内容本质上是随机的内核线程决不能修改其内容故将mm设置为NULL同时如果切换出去的是用户进程内核将原来进程的mm存放在新内核线程的active_mm中因为某些时候内核必须知道用户空间当前包含了什么。 为什么没有mm指针的进程称为惰性TLB进程?假如内核线程之后运行的进程与之前是同一个, 在这种情况下, 内核并不需要修改用户空间地址表。地址转换后备缓冲器(即TLB)中的信息仍然有效。只有在内核线程之后, 执行的进程是与此前不同的用户层进程时, 才需要切换(并对应清除TLB数据)。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间mm指针被设置为NULL它只在 内核空间运行从来不切换到用户空间去并且和普通进程一样可以被调度也可以被抢占。 内核线程的创建创建内核线程接口的演变内核线程可以通过两种方式实现 古老的接口 kernel_create和daemonize将一个函数传递给kernel_thread创建并初始化一个task该函数接下来负责帮助内核调用daemonize已转换为内核守护进程daemonize随后完成一些列操作, 如该函数释放其父进程的所有资源不然这些资源会一直锁定直到线程结束。阻塞信号的接收, 将init用作守护进程的父进程更加现在的方法kthead_create和kthread_run创建内核更常用的方法是辅助函数kthread_create该函数创建一个新的内核线程。最初线程是停止的需要使用wake_up_process启动它。使用kthread_run与kthread_create不同的是其创建新线程后立即唤醒它其本质就是先用kthread_create创建一个内核线程然后通过wake_up_process唤醒它 2号进程kthreadd的诞生早期的kernel_create和daemonize接口 在早期的内核中, 提供了kernel_create和daemonize接口, 但是这种机制操作复杂而且将所有的任务交给内核去完成。 但是这种机制低效而且繁琐, 将所有的操作塞给内核, 我们创建内核线程的初衷不本来就是为了内核分担工作, 减少内核的开销的么 Workqueue机制 因此在linux-2.6以后, 提供了更加方便的接口kthead_create和kthread_run, 同时将内核线程的创建操作延后, 交给一个工作队列workqueue, 参见http://lxr.linux.no/linuxv2.6.13/kernel/kthread.c#L21 Linux中的workqueue机制就是为了简化内核线程的创建。通过kthread_create并不真正创建内核线程, 而是将创建工作create work插入到工作队列helper_wq中, 随后调用workqueue的接口就能创建内核线程。并且可以根据当前系统CPU的个数创建线程的数量使得线程处理的事务能够并行化。workqueue是内核中实现简单而有效的机制他显然简化了内核daemon的创建方便了用户的编程. 工作队列workqueue是另外一种将工作推后执行的形式.工作队列可以把工作推后交由一个内核线程去执行也就是说这个下半部分可以在进程上下文中执行。最重要的就是工作队列允许被重新调度甚至是睡眠。具体的信息, 请参见Linux workqueue工作原理2号进程kthreadd 但是这种方法依然看起来不够优美, 我们何不把这种创建内核线程的工作交给一个特殊的内核线程来做呢 于是linux-2.6.22引入了kthreadd进程, 并随后演变为2号进程, 它在系统初始化时同1号进程一起被创建(当然肯定是通过kernel_thread), 参见rest_init函数, 并随后演变为创建内核线程的真正建造师, 参见kthreadd和kthreadd函数, 它会循环的是查询工作链表static LIST_HEAD(kthread_create_list);中是否有需要被创建的内核线程, 而我们的通过kthread_create执行的操作, 只是在内核线程任务队列kthread_create_list中增加了一个create任务, 然后会唤醒kthreadd进程来执行真正的创建操作  内核线程会出现在系统进程列表中, 但是在ps的输出中进程名command由方括号包围, 以便与普通进程区分。 如下图所示, 我们可以看到系统中, 所有内核线程都用[]标识, 而且这些进程父进程id均是2, 而2号进程kthreadd的父进程是0号进程 使用ps -eo pid,ppid,commandkernel_threadkernel_thread是最基础的创建内核线程的接口, 它通过将一个函数直接传递给内核来创建一个进程, 创建的进程运行在内核空间, 并且与其他进程线程共享内核虚拟地址空间 kernel_thread的实现经历过很多变革 早期的kernel_thread执行更底层的操作, 直接创建了task_struct并进行初始化, 引入了kthread_create和kthreadd 2号进程后, kernel_thread的实现也由统一的_do_fork(或者早期的do_fork)托管实现 早期实现 早期的内核中, kernel_thread并不是使用统一的do_fork或者_do_fork这一封装好的接口实现的, 而是使用更底层的细节 参见http://lxr.free-electrons.com/source/kernel/fork.c?v2.4.37#L613我们可以看到它内部调用了更加底层的arch_kernel_thread创建了一个线程 arch_kernel_thread其具体实现请参见http://lxr.free-electrons.com/ident?v2.4.37;iarch_kernel_thread但是这种方式创建的线程并不适合运行因此内核提供了daemonize函数, 其声明在include/linux/sched.h中 // http://lxr.free-electrons.com/source/include/linux/sched.h?v2.4.37#L800 extern void daemonize(void); 12 定义在kernel/sched.c http://lxr.free-electrons.com/source/kernel/sched.c?v2.4.37#L1326主要执行如下操作 该函数释放其父进程的所有资源不然这些资源会一直锁定直到线程结束。阻塞信号的接收将init用作守护进程的父进程 我们可以看到早期内核的很多地方使用了这个接口, 比如 可以参见http://lxr.free-electrons.com/ident?v2.4.37;idaemonize我们将了这么多kernel_thread, 但是我们并不提倡我们使用它, 因为这个是底层的创建内核线程的操作接口, 使用kernel_thread在内核中执行大量的操作, 虽然创建的代价已经很小了, 但是对于追求性能的linux内核来说还不能忍受 因此我们只能说kernel_thread是一个古老的接口, 内核中的有些地方仍然在使用该方法, 将一个函数直接传递给内核来创建内核线程 新版本的实现 于是linux-3.x下之后, 有了更好的实现, 那就是 延后内核的创建工作, 将内核线程的创建工作交给一个内核线程来做, 即kthreadd 2号进程 但是在kthreadd还没创建之前, 我们只能通过kernel_thread这种方式去创建,  同时kernel_thread的实现也改为由_do_fork(早期内核中是do_fork)来实现, 参见kernel/fork.c pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) {return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,(unsigned long)arg, NULL, NULL, 0); } 12345 kthread_createstruct task_struct *kthread_create_on_node(int (*threadfn)(void *data),void *data,int node,const char namefmt[], ...);#define kthread_create(threadfn, data, namefmt, arg...) \kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg) 1234567 创建内核更常用的方法是辅助函数kthread_create该函数创建一个新的内核线程。最初线程是停止的需要使用wake_up_process启动它。 kthread_run/*** kthread_run - create and wake a thread.* threadfn: the function to run until signal_pending(current).* data: data ptr for threadfn.* namefmt: printf-style name for the thread.** Description: Convenient wrapper for kthread_create() followed by* wake_up_process(). Returns the kthread or ERR_PTR(-ENOMEM).*/ #define kthread_run(threadfn, data, namefmt, ...) \ ({ \struct task_struct *__k \ kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \if (!IS_ERR(__k)) \wake_up_process(__k); \__k; \ })123456789101112131415161718 使用kthread_run与kthread_create不同的是其创建新线程后立即唤醒它其本质就是先用kthread_create创建一个内核线程然后通过wake_up_process唤醒它 内核线程的退出线程一旦启动起来后会一直运行除非该线程主动调用do_exit函数或者其他的进程调用kthread_stop函数结束线程的运行。int kthread_stop(struct task_struct *thread); 1 kthread_stop() 通过发送信号给线程。 如果线程函数正在处理一个非常重要的任务它不会被中断的。当然如果线程函数永远不返回并且不检查信号它将永远都不会停止。 在执行kthread_stop的时候目标线程必须没有退出否则会Oops。原因很容易理解当目标线程退出的时候其对应的task结构也变得无效kthread_stop引用该无效task结构就会出错。 为了避免这种情况需要确保线程没有退出其方法如代码中所示 thread_func() {// do your work here// wait to exitwhile(!thread_could_stop()){wait();} }exit_code() {kthread_stop(_task); //发信号给task通知其可以退出了 } 1234567891011121314 这种退出机制很温和一切尽在thread_func()的掌控之中线程在退出时可以从容地释放资源而不是莫名其妙地被人“暗杀”。
http://www.zqtcl.cn/news/471375/

相关文章:

  • 下载可以做动漫的我的世界视频网站长沙网站seo技巧
  • 汕头网站制作推荐制作影视视频的软件
  • 定制程序网站宁波英文网站建设
  • 安康公司做网站网页设计怎么设计
  • 小型企业网站系统南京seo外包平台
  • 曲靖网站制作邢台网站制作那家便宜
  • wordpress中portfolio重庆网站seo按天计费
  • 做淘客网站需要多大的空间工程公司名称大全简单大气
  • 康县建设局网站网站做优化
  • 笔记网站开发代码下载了wordpress后
  • 北京招聘高级网站开发工程师域名最新通知
  • 企业如何实现高端网站建设西安百度推广开户
  • 广西城乡住房建设厅网站首页本地 安装 WordPress主题
  • 网站开发 技术方案设计一个软件需要多少钱
  • 网站如何做死链接提交建设银行网站官网网址
  • 网站难做吗承德平台
  • 手机备案网站营销网络建设怎么写
  • 建个网站要花多少钱WordPress密码重设怎么改
  • 招商网站建设免费网站改版 升级的目的
  • 安徽圣力建设集团网站如何自己开发微信小程序
  • 学院网站板块盘多多搜索引擎入口
  • 网站seo内部优化wordpress建站网站报错
  • 网站建设科技国外网站入口
  • 怎样用网站做淘宝推广免费的项目管理软件
  • 共青城网站建设微网站开发报价
  • 网站建设选超速云建站网站建设公司比较
  • 芜湖网络科技有限公司沈阳网站推广优化公司哪家好
  • 自己制作图片文字图片网站建设和优化内容最重要性
  • 邢台做网站优化建筑行业新闻资讯
  • 站长统计app最新版本2023网站标题是关键词吗