Linux的进程、线程、文件描述符是什么

说到进程,恐怕面试中最常见的问题就是线程和进程的关系了,那么先说一下答案:在 Linux 系统中,进程和线程几乎没有区别

Linux 中的进程就是一个数据结构,看明白就可以理解文件描述符、重定向、管道命令的底层工作原理,最后我们从操作系统的角度看看为什么说线程和进程基本没有区别。

一、进程是什么

首先,抽象地来说,我们的计算机就是这个东西:

这个大的矩形表示计算机的内存空间,其中的小矩形代表进程,左下角的圆形表示磁盘,右下角的图形表示一些输入输出设备,比如鼠标键盘显示器等等。另外,注意到内存空间被划分为了两块,上半部分表示用户空间,下半部分表示内核空间

用户空间装着用户进程需要使用的资源,比如你在程序代码里开一个数组,这个数组肯定存在用户空间;内核空间存放内核进程需要加载的系统资源,这一些资源一般是不允许用户访问的。但是注意有的用户进程会共享一些内核空间的资源,比如一些动态链接库等等。

我们用 C 语言写一个 hello 程序,编译后得到一个可执行文件,在命令行运行就可以打印出一句 hello world,然后程序退出。在操作系统层面,就是新建了一个进程,这个进程将我们编译出来的可执行文件读入内存空间,然后执行,最后退出。

你编译好的那个可执行程序只是一个文件,不是进程,可执行文件必须要载入内存,包装成一个进程才能真正跑起来。进程是要依靠操作系统创建的,每个进程都有它的固有属性,比如进程号(PID)、进程状态、打开的文件等等,进程创建好之后,读入你的程序,你的程序才被系统执行。

那么,操作系统是如何创建进程的呢?对于操作系统,进程就是一个数据结构,我们直接来看 Linux 的源码:

struct task_struct {// 进程状态long              state;// 虚拟内存结构体struct mm_struct  *mm;// 进程号pid_t             pid;// 指向父进程的指针struct task_struct __rcu  *parent;// 子进程列表struct list_head        children;// 存放文件系统信息的指针struct fs_struct        *fs;// 一个数组,包含该进程打开的文件指针struct files_struct     *files;
};

task_struct就是 Linux 内核对于一个进程的描述,也可以称为「进程描述符」。源码比较复杂,我这里就截取了一小部分比较常见的。

其中比较有意思的是mm指针和files指针。mm指向的是进程的虚拟内存,也就是载入资源和可执行文件的地方;files指针指向一个数组,这个数组里装着所有该进程打开的文件的指针。

二、文件描述符是什么

先说files,它是一个文件指针数组。一般来说,一个进程会从files[0]读取输入,将输出写入files[1],将错误信息写入files[2]

举个例子,以我们的角度 C 语言的printf函数是向命令行打印字符,但是从进程的角度来看,就是向files[1]写入数据;同理,scanf函数就是进程试图从files[0]这个文件中读取数据。

每个进程被创建时,files的前三位被填入默认值,分别指向标准输入流、标准输出流、标准错误流。我们常说的「文件描述符」就是指这个文件指针数组的索引,所以程序的文件描述符默认情况下 0 是输入,1 是输出,2 是错误。

我们可以重新画一幅图:

对于一般的计算机,输入流是键盘,输出流是显示器,错误流也是显示器,所以现在这个进程和内核连了三根线。因为硬件都是由内核管理的,我们的进程需要通过「系统调用」让内核进程访问硬件资源。

PS:不要忘了,Linux 中一切都被抽象成文件,设备也是文件,可以进行读和写。

如果我们写的程序需要其他资源,比如打开一个文件进行读写,这也很简单,进行系统调用,让内核把文件打开,这个文件就会被放到files的第 4 个位置:

明白了这个原理,输入重定向就很好理解了,程序想读取数据的时候就会去files[0]读取,所以我们只要把files[0]指向一个文件,那么程序就会从这个文件中读取数据,而不是从键盘:

$ command < file.txt

同理,输出重定向就是把files[1]指向一个文件,那么程序的输出就不会写入到显示器,而是写入到这个文件中:

$ command > file.txt

错误重定向也是一样的,就不再赘述。

管道符其实也是异曲同工,把一个进程的输出流和另一个进程的输入流接起一条「管道」,数据就在其中传递,不得不说这种设计思想真的很优美:

$ cmd1 | cmd2 | cmd3

到这里,你可能也看出「Linux 中一切皆文件」设计思路的高明了,不管是设备、另一个进程、socket 套接字还是真正的文件,全部都可以读写,统一装进一个简单的files数组,进程通过简单的文件描述符访问相应资源,具体细节交于操作系统,有效解耦,优美高效。

三、线程是什么

首先要明确的是,多进程和多线程都是并发,都可以提高处理器的利用效率,所以现在的关键是,多线程和多进程有啥区别。

为什么说 Linux 中线程和进程基本没有区别呢,因为从 Linux 内核的角度来看,并没有把线程和进程区别对待。

我们知道系统调用fork()可以新建一个子进程,函数pthread()可以新建一个线程。但无论线程还是进程,都是用task_struct结构表示的,唯一的区别就是共享的数据区域不同

换句话说,线程看起来跟进程没有区别,只是线程的某些数据区域和其父进程是共享的,而子进程是拷贝副本,而不是共享:

就比如说,mm结构和files结构在线程中都是共享的:

所以说,我们的多线程程序要利用锁机制,避免多个线程同时往同一区域写入数据,否则可能造成数据错乱。

那么你可能问,既然进程和线程差不多,而且多进程数据不共享,即不存在数据错乱的问题,为什么多线程的使用比多进程普遍得多呢

因为现实中数据共享的并发更普遍呀,比如十个人同时从一个账户取十元,我们希望的是这个共享账户的余额正确减少一百元,而不是希望每人获得一个账户的拷贝,每个拷贝账户减少十元。

当然,必须要说明的是,只有 Linux 系统将线程看做共享数据的进程,不对其做特殊看待,其他的很多操作系统是对线程和进程区别对待的,线程有其特有的数据结构,我个人认为不如 Linux 的这种设计简洁,增加了系统的复杂度。

在 Linux 中新建线程和进程的效率都是很高的,对于新建进程时内存区域拷贝的问题,Linux 采用了 copy-on-write 的策略优化,也就是并不真正复制父进程的内存空间,而是等到需要写操作时才去复制。所以 Linux 中新建进程和新建线程都是很迅速的

Ref: https://github.com/labuladong/fucking-algorithm/blob/master/%E6%8A%80%E6%9C%AF/linux%E8%BF%9B%E7%A8%8B.md


Kotlin开发者社区

专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。

High availability, high performance, high real-time large-scale distributed system architecture design

分布式框架:Zookeeper、分布式中间件框架等
分布式存储:GridFS、FastDFS、TFS、MemCache、redis等
分布式数据库:Cobar、tddl、Amoeba、Mycat
云计算、大数据、AI算法
虚拟化、云原生技术
分布式计算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信机制:Dubbo、RPC调用、共享远程数据、消息队列等
消息队列MQ:Kafka、MetaQ,RocketMQ
怎样打造高可用系统:基于硬件、软件中间件、系统架构等一些典型方案的实现:HAProxy、基于Corosync+Pacemaker的高可用集群套件中间件系统
Mycat架构分布式演进
大数据Join背后的难题:数据、网络、内存和计算能力的矛盾和调和
Java分布式系统中的高性能难题:AIO,NIO,Netty还是自己开发框架?
高性能事件派发机制:线程池模型、Disruptor模型等等。。。

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。不积跬步,无以至千里;不积小流,无以成江河。

Kotlin 简介

Kotlin是一门非研究性的语言,它是一门非常务实的工业级编程语言,它的使命就是帮助程序员们解决实际工程实践中的问题。使用Kotlin 让 Java程序员们的生活变得更好,Java中的那些空指针错误,浪费时间的冗长的样板代码,啰嗦的语法限制等等,在Kotlin中统统消失。Kotlin 简单务实,语法简洁而强大,安全且表达力强,极富生产力。

Java诞生于1995年,至今已有23年历史。当前最新版本是 Java 9。在 JVM 生态不断发展繁荣的过程中,也诞生了Scala、Groovy、Clojure 等兄弟语言。

Kotlin 也正是 JVM 家族中的优秀一员。Kotlin是一种现代语言(版本1.0于2016年2月发布)。它最初的目的是像Scala那样,优化Java语言的缺陷,提供更加简单实用的编程语言特性,并且解决了性能上的问题,比如编译时间。 JetBrains在这些方面做得非常出色。

Kotlin语言的特性

用 Java 开发多年以后,能够尝试一些新的东西真是太棒了。如果您是 Java 开发人员,使用 Kotlin 将会非常自然流畅。如果你是一个Swift开发者,你将会感到似曾相识,比如可空性(Nullability)。 Kotlin语言的特性有:

1.简洁

大幅减少样板代码量。

2.与Java的100%互操作性

Kotlin可以直接与Java类交互,反之亦然。这个特性使得我们可以直接重用我们的代码库,并将其迁移到 Kotlin中。由于Java的互操作性几乎无处不在。我们可以直接访问平台API以及现有的代码库,同时仍然享受和使用 Kotlin 的所有强大的现代语言功能。

3.扩展函数

Kotlin 类似于 C# 和 Gosu, 它提供了为现有类提供新功能扩展的能力,而不必从该类继承或使用任何类型的设计模式 (如装饰器模式)。

4.函数式编程

Kotlin 语言一等支持函数式编程,就像Scala一样。具备高阶函数、Lambda 表达式等函数式基本特性。

5.默认和命名参数

在Kotlin中,您可以为函数中的参数设置一个默认值,并给每个参数一个名称。这有助于编写易读的代码。

6.强大的开发工具支持

而由于是JetBrains出品,我们拥有很棒的IDE支持。虽然Java到Kotlin的自动转换并不是100% OK 的,但它确实是一个非常好的工具。使用 IDEA 的工具转换Java代码为 Kotlin 代码时,可以轻松地重用60%-70%的结果代码,而且修改成本很小。

Kotlin 除了简洁强大的语法特性外,还有实用性非常强的API以及围绕它构建的生态系统。例如:集合类 API、IO 扩展类、反射API 等。同时 Kotlin 社区也提供了丰富的文档和大量的学习资料,还有在线REPL。

A modern programming language that makes developers happier. Open source forever

图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)

图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)

https://kotlinlang.org/


http://www.taodudu.cc/news/show-2355950.html

相关文章:

  • UML类图详细介绍
  • 川土微电子 | CA-IS3050U隔离式CAN收发器
  • 土木学matlab还是python_五行属土的字大全
  • 合抱之木,生于毫末。九层之台,起于累土。千里之行,始于足下
  • UML - 类图的关系总结
  • JAVA基础之异常
  • 九尺之台,始于垒土
  • Android 设计素材积累(九层之台起于垒土)
  • 初识Python必看基础知识~ 续(6)九层之台,起于垒土,肝肝肝~
  • 九层之台,起于垒土
  • 文学de垒土
  • 九层之台,始于垒土;合抱之木,始于毫末;千里之行,始于足下!
  • 合抱之木,生于毫末; 九层之台,起于垒土。
  • Android APP安全测试
  • 【电子商务法】北邮国际学院大三上期末复习
  • 大数据架构和模式
  • 2020上半年DeFi行业研究报告-Part2 发行 | TokenInsight
  • 独家研究 I 某新一线城市中高端养老社区项目(CCRC)入住客户画像深度洞察研究报告
  • Java基础:第5-6章(重点)
  • 刑事实务办案中疑难问题
  • 正确认识P2P,从容面对风暴
  • 当前网络安全风险及举例
  • 互联网金融学习总结(1)——互联网金融(ITFIN)概念相关学习
  • Chainlink的77种用法
  • 合同法律风险管理 被骗者刑事风险
  • 8 种流行的计算机视觉应用
  • 如何区分P2P是互联网创新还是非法集资?最高检回应
  • 肖飒:区块链应用创业的法律边界及案例分析 | 清华x-lab公开课
  • 张明楷的100个刑法案例
  • 银行网站 ca服务器的安装,建行网银CA认证系统建设案例介绍

一切皆是文件:UNIX,Linux 操作系統的設計哲學相关推荐

  1. linux安装定制添加输入,Arch Linux--定制自己的Linux操作系統(乙-國際化桌面安裝篇)...

    Arch Linux--定制自己的Linux操作系統 ----乙-國際化&桌面安裝篇 相信大家看了<甲-安裝篇>之後,Arch Linux系統已經可以正常運行了吧?不過,Arch ...

  2. doc unix linux,[整理]unix,linux操作系统概述及基本知识.doc

    [整理]unix,linux操作系统概述及基本知识.doc unix,linuxunix,linux 操作系统概述及基本知识操作系统概述及基本知识unix,linux 操作系统概述 及基本 知识 un ...

  3. Unix/Linux操作系统分析实验二 内存分配与回收:Linux系统下利用链表实现动态内存分配

    Unix/Linux操作系统分析实验一 进程控制与进程互斥 Unix/Linux操作系统分析实验三 文件操作算法: 实现在/proc目录下添加文件 Unix/Linux操作系统分析实验四 设备驱动: ...

  4. linux上搭载was应用上传中文文件,受支持的Linux操作系统和WAS ND 9.0安装部署文档的资料说明...

    本文档的主要内容详细介绍的是受支持的Linux操作系统和WAS ND 9.0安装部署文档的资料说明. 从was9.0开始支持的最低版本的red hat Linux系统为6.6且仅支持64位操作系统 计 ...

  5. Unix/Linux操作系统分析实验四 设备驱动: Linux系统下的字符设备驱动程序编程

    Unix/Linux操作系统分析实验一 进程控制与进程互斥 Unix/Linux操作系统分析实验二 内存分配与回收:Linux系统下利用链表实现动态内存分配 Unix/Linux操作系统分析实验三 文 ...

  6. php linux脚本文件,Unix/Linux中如何直接执行PHP脚本文件?

    使用Linux系统的服务器都有搭建完整的PHP环境,因此有些用户会用PHP去写一些执行自动化任务的脚本,可是发现每次执行PHP脚本都需要使用php myscript.php的方式,感觉有点麻烦.其实我 ...

  7. linux msgsend 头文件,Unix/Linux进程间通信

    一,Linux下进程间通信的几种主要手段简介: 1,管道(Pipe)及有名管道(named pipe) 管道可用于具有亲缘关系进程间的通信 有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功 ...

  8. 操作系統恐龍書第十版課後答案 ch08

    8.1 List three examples of deadlocks that are not related to a computersystem environment. a.兩輛車從相反方 ...

  9. 中國IT從業人員如此之多,為什麼沒有流行世界的核心技術呢?例如,操作系統,編程語言,數據庫等...

    工业革命与文艺复兴 18世紀中葉,英國人瓦特改良蒸汽機之後,一系列技術革命引起了從手工勞動向動力機器生產轉變的重大飛躍.隨後傳播到英格蘭到整個歐洲大陸,19世紀傳播到北美地區.工業革命的基礎,是物理和 ...

  10. linux文件权限包括哪三种,unix/linux操作系统对文件进行操作时有哪三类用户,这些用户可能拥有的权限有哪些?...

    寂寞在唱歌,寂寞也在膨胀.午夜十二点,女友依然没有回来,没有熟悉的脚步声,也没有熟悉的敲门声.方才还人声鼎沸,现在,喧闹已经停止,黑夜并没有随着街灯的闪亮而有所收敛. 相反,一盏盏昏黄的街灯的陆续亮起 ...

最新文章

  1. 时间复杂度和空间复杂度3 - 数据结构和算法05
  2. 数列分块入门2(区间小于c的个数)
  3. mac 安装配置java环境变量
  4. OpenCV使用Shi-Tomasi方法检测拐角的实例(附完整代码)
  5. Java Error(三)
  6. 花椒web端实时互动流媒体播放器
  7. asp.net 导出Excel 设置格式
  8. Javascript、Jquery获取浏览器和屏幕各种高度宽度
  9. ICS Pwn2Own 2022迈阿密黑客大赛的目标和奖金公布
  10. python dlib gpu ubuntu conda_Ubuntu 下编译支持 GPU 的 TensorFlow 和 Dlib
  11. 华为查看mpls的命令_华为BGP基本命令
  12. 南信大学生怎样看知网,看外文文献
  13. 汇集各种 webservice工厂,快递,ip,天气,身份证,手机,翻译,火车时刻,股票,邮编,二维码,公交,ISBN,ICP 查询接口 API
  14. ico的尺寸_Favicon.ico浏览器图标文件制作和正确使用
  15. 关于钓鱼网站的实现原理与技术
  16. html图片在wps中不显示文字大小,WPS文字插入图片显示不全怎么办 WPS文字插入图片显示不完整的解决方法...
  17. jboot 配置durid + logback debug打印 sql+执行参数(非?)
  18. AI插画师:生成对抗网络
  19. 第一篇 安卓系统的介绍及特点
  20. Seata遇到的问题

热门文章

  1. 月薪达到1万的web前端工程师,都会些什么呢?(附路线资料)
  2. delphi xe 10 程式外观
  3. 新的开始——参加培训
  4. poj 2825 蜜汁构造
  5. 流量卡之家:物联网系统解决交通拥堵 全面开启未来绿色出行
  6. VMware Esxi 下载地址
  7. 【CentOS8.0开启防火墙放行8081端口】
  8. 用计算机实测技术研究声波和拍内容,大学物理实验
  9. 编程路上,对于迷失者的一些小小建议
  10. 制作u盘winpe启动盘_u盘启动盘制作工具 纯净+好用,原来不止是 微pe