网站开发团队/营销推广是什么意思
首先先来看一下内核态和用户态
刚开始看着一块,以前只是在大学期间的基本了解
先上一张图,c语言中最简单的操作:print操作
所有的硬件连接都基本上是由操作系统的内核态控制,那么这个print操作就涉及到键盘,显示器等物理I/O
执行步骤:
1.用户程序有一个语句调用了库函数printf(),在printf()函数中又通过一系列的函数调用,最终转到调用write()函数,
2.在write()函数对应的指令序列中,一定有一条用于系统调用的陷阱指令。该陷阱指令执行后,进程就从用户态陷入到内核态执行。
3.Linux中有一个系统调用的统一入口,即系统调用处理程序system_call()。CPU执行陷阱指令(Trap Instruction)后,便转到system_call()的第一条指令执行。在system_call()中,将根据EAX寄存器中的系统调用号跳转到当前的系统调用服务例程sys_write()去执行。
4.system_call()执行结束时,从内核态返回到用户态下的陷阱指令后面一条指令继续执行。
那么这个系统指令执行的过程中,在单核CPU和多核CPU的区别又是什么呢?
在多线程情况下,对于多核CPU的利用率有没有什么提升呢?
首先epoll已经在内核态上帮我们做了硬件的优化,那么在用户需要做的就是平衡CPU计算和IO计算
select、poll、epoll都是IO多路复用的机制,但是他们的机制有很大的区别
1、select select机制刚开始的时候,需要把fd_set从用户空间拷贝到内核空间,并且检测的fd数是有限制的,由FD_SETSIZE设置,一般是1024。检测的时候,根据timeout,遍历fd_set表,把活跃的fd(可读写或者错误),拷贝到用户空间,再在用户空间依次处理相关的fd。
这个机制是linux内核很早的版本,epool是根据select,pool基础上优化的,缺点比较多。
缺点:
1)每次调用select的时候需要把fd_set从用户空间拷贝到内存空间,比较耗性能。
2)wait时,需要遍历所有的fd,消耗比较大。
3)select支持的文件数大小了,默认只有1024,如果需要增大,得修改宏FD_SETSIZE值,并编译内核(麻烦,并且fd_set中的文件数多的话,每次遍历的成本就很大)。
2. poolpoll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。3. epoolepool是select和poll的改进版本,
* 先是使用int epoll_create(int size)在内存中创建一个指定size大小的事件空间,
* 再使用int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);事件注册函数,注册新的fd到epfd的epool对象空间中,并指明event(可读写啊等等),注意:在注册新事件fd的过程中,也再内核中断处理程序里注册fd对应的回调函数callback,告诉内核,一旦这个fd中断了,就把它放到ready队列里面去。
* 再使用int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);在epool对象对应的ready队列里取就绪的fd,并使用内存映射mmap拷贝到用户空间。
* 再在用户空间依次处理相关的fd。
优点:
1)支持一个进程打开大数目的socket描述符select 一个进程打开FD是有限制的,由FD_SETSIZE设置,默认值是1024。epool可以打开的FD数可以很大,一般1GB的内存有10万多的FD数,具体数目可以cat /proc/sys/fs/file-max查看。
2) IO效率不随FD数目增加而线性下降
3) 使用mmap加速内核与用户空间的消息传递
很多人都知道线程数不是越多越好,但是设置多少是合适的,却又拿不定主意。其实只要把握住一条原则就可以了。
这条原则就是将硬件的性能发挥到极致。
具体的网上有很多例子,我就不在此瞎扯淡了
对了今天看了个讲解CAP的:https://mp.weixin.qq.com/s/Fj4zERz9PEuNumd_SI0bEA
上面的还没有玩,后面有时间补充