热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

LINUX进程,线程

http:shaohui.mearchives256N久之前,某两人为了linux的调度基本单元是进程还是线程争得面红耳赤,当然,且不论为了一个技术问题不顾体面其用心何在,单纯从技

http://shaohui.me/archives/256

 N久之前, 某两人为了linux的调度基本单元是进程还是线程争得面红耳赤, 当然, 且不论为了一个技术问题不顾体面其用心何在, 单纯从技术角度讲, 这是个挺好的问题.


    单纯的下一个结论几乎总是错误的, 所谓的对与错也只不过是在特定的时段和特定的场景下符合规律的一种状态, 一旦时过境迁, 对的东西往往变成了错误的, 而错误的东西又会变成对的.所以我建议在这里不要使用"对"或是"错"来判定事务, 只能说是在当前的情况下, 从UUU角度看XXX更显得更"符合实际". 
    我们都知道linux是不断发展的.在早期版本中, linux的基本调度单元是Task, 只到现在, 依然是它. 
    在早期版本中, 一个Task对应着一个进程, 完全没有线程这个概念. 
    随着时间的发展, 线程的概念出现的, 但是linux并没有马上接受这一概念, 要知道, 线程是现代操作系统的特征, 向一个现有的操作系统内核引入线程是一件伤筋动骨的事情, 更何况在线程概念的早期, 受历史原因(UNIX)和硬件的限制(多核尚不是主流), 线程的地位尚不确定. 所以, linux并没有在内核中引入线程的概念. 
    但是, linux提供了一个新的系统调用clone, 通过该系统调用, 内核中的多个进程可以共享一些信息, 比如进程空间等. 注意, 此时linux内核的基础调度单元依然是Task, 而且在内核看来, 一个进程依然对应着一个Task. 
    有了clone系统调用, 人们在用户态就可以模拟出线程的行为. 但是, 内核并没有线程的概念, 他依然将所有的进程看着是独立的. 这个用户态模拟的线程现实是linux pthread lib.
    虽然可以在一定程度上模仿出线程的行为, 但是那些只有在内核中才能实现的线程的行为, 在用户态是模拟不了的. 而且, 随着时间的发展, 内核技术的进步, 已经多核的普及, 促生了linux 2.6内核版本. 
    注意, linux kernel 2.6是一个飞跃性的版本, 大家都认同, 本次版本将linux从传统操作系统晋升为现代操作系统. 其中最重要的改进就是, 内核中引入了线程组的概念. 
    这里要分析一下, clone调用的引入, 使得两个进程可以共享一些资源, 但是内核依然将两个进程看做是独立的, 互不相关的. 它们拥有自己的独立进程id, 信号处理等等. 
    2.6 内核中引入了线程组的概念, 也就是说在clone调用时, 如果设置了适当的标志位(libc 的NPTL 库正确的实现了这一特性), 内核将把新创建的进程和原进程视为一个组, 这个组称之为"线程组", 组中的进程称之为"线程". 注意, 到了这一步, 内核的调度单元依然是Task, 在内核中, 每个Task对应着一个进程, 只不过, 这个进程有可能是一个单独的进程, 也有可能是一个"线程组"中的一个线程. 
    线程组中的所有线程(进程)共享同一个进程pid, 给线程组中的任何一个线程发送信号, 整个线程组中的线程都能收到信号.

    综上所述, 可以得出以下一些结论: 
    1. 内核的调度单元是Task 
    2. 2.6以前的内核中没有线程的概念. 每个Task对应一个进程. 
    3. 2.6以后的内核中增加了线程组的概念, 每个Task对应一个进程, 或者是一个线程组中的一个线程. 所谓的线程, 只是几个相关进程中的一个.

    进一步, 2.6的这种改法, 符合现代操作系统对于进程和线程的内涵. 因为在现代操作系统中: 
        进程: 提供计算资源. 
        线程: 进行计算. 
    从这个角度出发, 在2.6以后的linux中, 对于多线程程序, 我们可以看做是一个进程 + 多个线程. 对于单线程程序, 我们也可以看做是一个进程 + 一个线程. 在这样统一个看法中可以说一个Task对应一个线程, 进而得出"内核的调度单元是线程"的结论. 
    当然, 我们也可以不使用现代操作系统的观点, 这样的话, 对多线程程序, 我们可以看做是内核将多个进程组织起来形成的一个进程, 对于单线程程序, 我们就把它看做是一个进程, 进而也可以得出"内核的调度单元是进程"的结论. 
    其实真正重要的是, 系统是否给我们系统了符合线程行为定义的机制, 至于下面的实现是进程还是线程, 都不是我们关心的, 因为正是有了进程, 线程这样的抽象的概念, 我们才能够在更高的层面上认识问题, 更好的使用它们.

    所以, 争论内核的调度单元是Task, 进程, 线程, 其实是混淆了看问题的角度, 时空, 以及无法区分抽象和现实而产生的, 当然, 单纯的技术问题也可以用来当着"指鹿为马", 但别人看来只是一场笑话.

附一篇很好的文章, 比较详细的描述介绍了linux下的线程机制.



推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Linux下安装免费杀毒软件ClamAV及使用方法
    本文介绍了在Linux系统下安装免费杀毒软件ClamAV的方法,并提供了使用该软件更新病毒库和进行病毒扫描的指令参数。同时还提供了官方安装文档和下载地址。 ... [详细]
  • 第七课主要内容:多进程多线程FIFO,LIFO,优先队列线程局部变量进程与线程的选择线程池异步IO概念及twisted案例股票数据抓取 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • 本文总结了Linux下多线程执行shell脚本的4种方法,包括切换到工作目录执行、使用绝对路径执行、直接使用bash或sh执行。同时介绍了为什么需要加上"./"来执行脚本的原因。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • 本文介绍了在Ubuntu系统中清理残余配置文件和无用内容的方法,包括清理残余配置文件、清理下载缓存包、清理不再需要的包、清理无用的语言文件和清理无用的翻译内容。通过这些清理操作可以节省硬盘空间,提高系统的运行效率。 ... [详细]
  • 进入配置文件目录:[rootlinuxidcresin-4.0.]#cdusrlocalresinconf查看都有哪些配置文件:[rootlinuxid ... [详细]
  • UNIX高级环境编程 第11、12章 线程及其属性
    第11章线程11.2线程概念线程资源:线程ID,一组寄存器,栈,调度优先级和策略,信号屏蔽字,e ... [详细]
  • golang源码分析调度概述
    golang源码分析-调度过程概述本文主要概述一下golang的调度器的大概工作的流程,众所周知golang是基于用户态的协程的调度来完成多任务的执行。在Linux ... [详细]
  • Linux 中使用 clone 函数来创建线程
    2019独角兽企业重金招聘Python工程师标准Linux上创建线程一般使用的是pthread库实际上libc也给我们提供了创建线程的函数那就是cloneintclone(i ... [详细]
author-avatar
风清淡雅的梦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有