linux电流命令 linux cpu 电压( 二 )


第四个参数传入的是 需要操作的fd的哪些事件,具体的事件可以看后续 。
返回值是一个int类型,如果为-1则说明操作失败。
第一个参数是epfd,也就是epoll_create的返回值 。
第二个参数是一个epoll_event类型的指针,也就是传入的是一个数组指针 。内核会将就绪的socket的事件拷贝到这个数组中,用户可以根据这个数组拿到事件和消息等。
第三个参数是maxevents,传入的是 第二个参数的数组的容量。
第四个参数是timeout,如果设为-1一直阻塞直到有就绪数据为止 , 如果设为0立即返回 , 如果>0那么阻塞一段时间。
返回值是一个int类型 , 也就是就绪的socket的事件的数量(内核拷贝给用户的events的元素的数量),通过这个数量可以进行遍历处理每个事件。
一般需要传入 ev.data.fd 和 ev.events  , 也就是fd和需要监控的fd的事件 。事件如果需要传入多个,可以通过按位与来连接,比如需要监控读写事件,只需要像如下这样操作即可: ev.events=EPOLLIN | EPOLLOUT。
LT(水平触发),默认 的工作模式,事件就绪后用户可以选择处理和不处理,如果用户不处理,内核会对这部分数据进行维护 , 那么下次调用epoll_wait()时仍旧会打包出来。
ET(边缘触发) , 事件就绪之后,用户必须进行处理,因为内核把事件打包出来之后就把对应的就绪事件给清掉了, 如果不处理那么就绪事件就没了。ET可以减少epoll事件被重复触发的次数,效率比LT高 。
如果需要设置为边缘触发只需要设置事件为类似 ev.events=EPOLLIN | EPOLLET 即可。
select/poll/epoll是nio多路复用技术,传统的bio无法实现C10K/C100K ,也就是无法满足1w/10w的并发量,在这么高的并发量下,在进行上下文切换就很容易将服务器的负载拉飞 。
1.将fd_set从用户态拷贝到内核态
2.根据fd_set扫描内存中的socket的fd的状态,时间复杂度为O(n)
3.检查fd_set,如果有已经就绪的socket,就给对应的socket的fd打标记,那么就return 就绪socket的数量并唤醒当前线程 , 如果没有就绪的socket就继续阻塞当前线程直到有socket就绪才将当前线程唤醒 。
4.如果想要获取当前已经就绪的socket列表 , 则还需要进行一次系统调用,使用O(n)的时间去扫描socket的fd列表,将已经打上标记的socket的fd返回 。
CPU在同一个时刻只能执行一个程序 , 通过RR时间片轮转去切换执行各个程序 。没有被挂起的进程(线程)则在工作队列中排队等待CPU的执行,将进程(线程)从工作队列中移除就是挂起,反映到Java层面的就是线程的阻塞 。
什么是中断?当我们使用键盘、鼠标等IO设备的时候 , 会给主板一个电流信号,这个电流信号就给CPU一个中断信号,CPU执行完当前的指令便会保存现场,然后执行键盘/鼠标等设备的中断程序,让中断程序获取CPU的使用权,在中断程序后又将现场恢复,继续执行之前的进程 。
如果第一次没检测到就绪的socket , 就要将其进程(线程)从工作队列中移除,并加入到socket的等待队列中 。
socket包含读缓冲区+写缓冲区+等待队列(放线程或eventpoll对象)
当从客户端往服务器端发送数据时,使用TCP/IP协议将通过物理链路、网线发给服务器的网卡设备,网卡的DMA设备将接收到的的数据写入到内存中的一块区域(网卡缓冲区) , 然后会给CPU发出一个中断信号,CPU执行完当前指令则会保存现场 , 然后网卡的中断程序就获得了CPU的使用权,然后CPU便开始执行网卡的中断程序 , 将内存中的缓存区中的数据包拿出 , 判断端口号便可以判断它是哪个socket的数据,将数据包写入对应的socket的读(输入)缓冲区 , 去检查对应的socket的等待队列有没有等待着的进程(线程),如果有就将该线程(进程)从socket的等待队列中移除,将其加入工作队列,这时候该进程(线程)就再次拥有了CPU的使用权限 , 到这里中断程序就结束了 。