哪个网站做二手叉车回收好,怎么做网站的访问量,京东网站建设机构,平面设计图制作说到进程#xff0c;恐怕面试中最常见的问题就是线程和进程的关系了#xff0c;那么先说一下答案#xff1a;在 Linux 系统中#xff0c;进程和线程几乎没有区别。Linux 中的进程其实就是一个数据结构#xff0c;顺带可以理解文件描述符、重定向、管道命令的底层工作原理恐怕面试中最常见的问题就是线程和进程的关系了那么先说一下答案在 Linux 系统中进程和线程几乎没有区别。Linux 中的进程其实就是一个数据结构顺带可以理解文件描述符、重定向、管道命令的底层工作原理最后我们从操作系统的角度看看为什么说线程和进程基本没有区别。一、进程是什么首先抽象地来说我们的计算机就是这个东西这个大的矩形表示计算机的内存空间其中的小矩形代表进程左下角的圆形表示磁盘右下角的图形表示一些输入输出设备比如鼠标键盘显示器等等。另外注意到内存空间被划分为了两块上半部分表示用户空间下半部分表示内核空间。用户空间装着用户进程需要使用的资源比如你在程序代码里开一个数组这个数组肯定存在用户空间内核空间存放内核进程需要加载的系统资源这一些资源一般是不允许用户访问的。但是注意有的用户进程会共享一些内核空间的资源比如一些动态链接库等等。我们用 C 语言写一个 hello 程序编译后得到一个可执行文件在命令行运行就可以打印出一句 hello world然后程序退出。在操作系统层面就是新建了一个进程这个进程将我们编译出来的可执行文件读入内存空间然后执行最后退出。你编译好的那个可执行程序只是一个文件不是进程可执行文件必须要载入内存包装成一个进程才能真正跑起来。进程是要依靠操作系统创建的每个进程都有它的固有属性比如进程号(PID)、进程状态、打开的文件等等进程创建好之后读入你的程序你的程序才被系统执行。那么操作系统是如何创建进程的呢对于操作系统进程就是一个数据结构我们直接来看 Linux 的源码struct task_struct { // 进程状态 long state; // 虚拟内存结构体 struct mm_struct *mm; // 进程号 pid_t pid; // 指向父进程的指针 struct task_struct *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 个位置对应文件描述符 3明白了这个原理输入重定向就很好理解了程序想读取数据的时候就会去files[0]读取所以我们只要把files[0]指向一个文件那么程序就会从这个文件中读取数据而不是从键盘同理输出重定向就是把files[1]指向一个文件那么程序的输出就不会写入到显示器而是写入到这个文件中错误重定向也是一样的就不再赘述。管道符其实也是异曲同工把一个进程的输出流和另一个进程的输入流接起一条「管道」数据就在其中传递不得不说这种设计思想真的很巧妙到这里你可能也看出「Linux 中一切皆文件」设计思路的高明了不管是设备、另一个进程、socket 套接字还是真正的文件全部都可以读写统一装进一个简单的files数组进程通过简单的文件描述符访问相应资源具体细节交于操作系统有效解耦优美高效。三、线程是什么首先要明确的是多进程和多线程都是并发都可以提高处理器的利用效率所以现在的关键是多线程和多进程有啥区别。为什么说 Linux 中线程和进程基本没有区别呢因为从 Linux 内核的角度来看并没有把线程和进程区别对待。我们知道系统调用fork()可以新建一个子进程函数pthread()可以新建一个线程。但无论线程还是进程都是用task_struct结构表示的唯一的区别就是共享的数据区域不同。换句话说线程看起来跟进程没有区别只是线程的某些数据区域和其父进程是共享的而子进程是拷贝副本而不是共享。就比如说mm结构和files结构在线程中都是共享的我画两张图你就明白了所以说我们的多线程程序要利用锁机制避免多个线程同时往同一区域写入数据否则可能造成数据错乱。那么你可能问既然进程和线程差不多而且多进程数据不共享即不存在数据错乱的问题为什么多线程的使用比多进程普遍得多呢因为现实中数据共享的并发更普遍呀比如十个人同时从一个账户取十元我们希望的是这个共享账户的余额正确减少一百元而不是希望每人获得一个账户的拷贝每个拷贝账户减少十元。当然必须要说明的是只有 Linux 系统将线程看做共享数据的进程不对其做特殊看待其他的很多操作系统是对线程和进程区别对待的线程有其特有的数据结构我个人认为不如 Linux 的这种设计简洁增加了系统的复杂度。在 Linux 中新建线程和进程的效率都是很高的对于新建进程时内存区域拷贝的问题Linux 采用了 copy-on-write 的策略优化也就是并不真正复制父进程的内存空间而是等到需要写操作时才去复制。所以 Linux 中新建进程和新建线程都是很迅速的。以上就是全部内容如果有帮助的话不妨点个在看我看看操作系统相关的文章阅读数据怎么样不错的话以后可以再写写操作系统方面的小知识。