在牛客上看到一个非常经典的理论结合实际的例子,我觉得要记录下来,要好好照着这种多扩展
作者:程序员小北
来源:牛客网
。。。。。。
但是这还不够,看完偏理论的书,当面试官问「进程和线程的区别」时。
大概只能回答出「进程是资源分配的最小单位,线程是CPU调度的最小单位,balabala...」这样正确却普通的答案。
但是如果你了解 Linux 内核的实现,就可以实际出发,讲讲 Linux 中进程和线程是如何创建的,区别在哪里。
比如在 Linux 中进程和线程实际上都是用一个结构体 task_struct来表示一个执行任务的实体。进程创建调用fork 系统调用,而线程创建则是 pthread_create 方法,但是这两个方法最终都会调用到 do_fork 来做具体的创建操作 ,区别就在于传入的参数不同。
深究下去,你会发现 Linux 实现线程的方式简直太巧妙了,实际上根本没有线程,它创建的就是进程,只不过通过参数指定多个进程之间共享某些资源(如虚拟内存、页表、文件描述符等),函数调用栈、寄存器等线程私有数据则独立。
这样是不是非常符合理论书上的定义:同一进程内的多个线程共享该进程的资源,但线程并不拥有资源,只是使用他们。
这也算符合 Unix 的哲学了— KISS(Keep It Simple, Stupid)。
但是在其它提供了专门线程支持的系统中,则会在进程控制块(PCB)中增加一个包含指向该进程所有线程的指针,然后再每个线程中再去包含自己独占的资源。
这算是非常正统的实现方式了,比如 Windows 就是这样干的。
但是相比之下 Linux 就显得取巧很多,也很简洁。
对于进程、线程这块你还可以把 fork、vfork、clone 、pthread_create 这些模块关系彻底搞清楚,对你理解 Linux 下的进程实现有非常大的帮助。
说了这么多,就是想强调一下理论联系实际的重要性。
特别是操作系统,最好的实践就是看下 Linux 内核是怎么实现的,当然不是叫你直接去啃 Linux 源码,那不是一般人能掌握的。
最好的方式是看书,书的脉络给你理得很清晰。
。。。。。。
自己的扩展1:
os面经必问的一个问题:进程间通信的方式
主要有: 匿名管道、有名管道、内存映射、信号、消息队列、共享内存、信号量,socket
上面是最基本的回答,但是如果学习了linux多线程开发,了解实际中linux进程的实现原理,就可以进行深入的解释
例如:管道为什么分为匿名管道和有名管道?能详细介绍一下吗?
因为匿名管道是适用于有关系的进程,例如父子进程,在linux中,进程都有一个叫pcb的进程描述文件,在调用fork()函数创建子进程时,子进程的pcb是拷贝父进程的pcb而来的,子进程的pcb有很多数据和父进程保持一致,而pcb其中的文件描述符fd就有很多数据一样,通过相同的文件描述符就可以进行匿名管道通信。因为管道实际就是一种文件(当然,在linux上一切都是文件),匿名管道没有文件实体。
而没有关系的进程之间因为没有相同的文件描述符fd,所以没有亲缘关系的进程如果要通过管道通信,就必须是有名管道(有名管道有实体文件,有文件名,但是注意不存储数据)。
如果能在面试中将理论和实际之间的联系表达出来,必定能让面试官眼前一亮
内存映射、信号量等方式如果知晓其原理一样可以做出一些解释说明,
其他知识点以此类推。抛砖引玉。
如果能这样分析、思考知识点和问题,我觉得你对这个知识点的把握应该就很充分了!
例子2:
值传递和引用传递
标签:文件,结合实际,理论,引子,pcb,管道,线程,Linux,进程 From: https://www.cnblogs.com/libxing/p/16642495.html