【io_uring】liburing 用户库源码分析
文章目录
当前内容基于 liburing 2.1 版本
整体流程
之前有过总结,使用 io_uring 的一般流程如下:
- 使用
open
、fstat
等函数来打开文件以及元数据查看等操作- 因为 io_uring 替换的是读写接口,后续 io_uring 操作的对象是
fd
(由open
函数执行返回的)
- 因为 io_uring 替换的是读写接口,后续 io_uring 操作的对象是
- 使用
io_uring_queue_init
初始化struct io_uring ring
结构体 - 初始化
struct iovec *iovecs
结构体用于存放用户态 buffer 指针和长度 - 通过
io_uring_get_sqe
获取sqe
- 通过
io_uring_prep_#OP
对sqe
填充命令,buffer 以及 offset 信息- 【可选】 通过
io_uring_sqe_set_data
对sqe
附加user_data
信息(该信息会在cqe
中进行返回)
- 【可选】 通过
- 通过
io_uring_submit
对整个ring
的所有sqe
进行下发 - 通过
io_uring_wait_cqe
或者io_uring_peek_cqe
来获取cqe
io_uring_wait_cqe
会阻塞当前线程直到有一个cqe
返回io_uring_peek_cqe
不会阻塞,如果当前没有cqe
,就会返回错误io_uring_cqe_get_data
可以从cqe
中获取user_data
- 通过
io_uring_cqe_seen
对当前cqe
进行清除,避免被二次处理 - 所有 IO 完成后,通过
io_uring_queue_exit
将ring
销毁
io_uring_queue_init
函数调用逻辑
#mermaid-svg-H3yetaxX7jDQBCcY .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-H3yetaxX7jDQBCcY .label text{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .node rect,#mermaid-svg-H3yetaxX7jDQBCcY .node circle,#mermaid-svg-H3yetaxX7jDQBCcY .node ellipse,#mermaid-svg-H3yetaxX7jDQBCcY .node polygon,#mermaid-svg-H3yetaxX7jDQBCcY .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-H3yetaxX7jDQBCcY .node .label{text-align:center;fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .node.clickable{cursor:pointer}#mermaid-svg-H3yetaxX7jDQBCcY .arrowheadPath{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-H3yetaxX7jDQBCcY .flowchart-link{stroke:#333;fill:none}#mermaid-svg-H3yetaxX7jDQBCcY .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-H3yetaxX7jDQBCcY .edgeLabel rect{opacity:0.9}#mermaid-svg-H3yetaxX7jDQBCcY .edgeLabel span{color:#333}#mermaid-svg-H3yetaxX7jDQBCcY .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-H3yetaxX7jDQBCcY .cluster text{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-H3yetaxX7jDQBCcY .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-H3yetaxX7jDQBCcY text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-H3yetaxX7jDQBCcY .actor-line{stroke:grey}#mermaid-svg-H3yetaxX7jDQBCcY .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-H3yetaxX7jDQBCcY .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-H3yetaxX7jDQBCcY #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-H3yetaxX7jDQBCcY .sequenceNumber{fill:#fff}#mermaid-svg-H3yetaxX7jDQBCcY #sequencenumber{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY #crosshead path{fill:#333;stroke:#333}#mermaid-svg-H3yetaxX7jDQBCcY .messageText{fill:#333;stroke:#333}#mermaid-svg-H3yetaxX7jDQBCcY .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-H3yetaxX7jDQBCcY .labelText,#mermaid-svg-H3yetaxX7jDQBCcY .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-H3yetaxX7jDQBCcY .loopText,#mermaid-svg-H3yetaxX7jDQBCcY .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-H3yetaxX7jDQBCcY .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-H3yetaxX7jDQBCcY .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-H3yetaxX7jDQBCcY .noteText,#mermaid-svg-H3yetaxX7jDQBCcY .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-H3yetaxX7jDQBCcY .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-H3yetaxX7jDQBCcY .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-H3yetaxX7jDQBCcY .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-H3yetaxX7jDQBCcY .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .section{stroke:none;opacity:0.2}#mermaid-svg-H3yetaxX7jDQBCcY .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-H3yetaxX7jDQBCcY .section2{fill:#fff400}#mermaid-svg-H3yetaxX7jDQBCcY .section1,#mermaid-svg-H3yetaxX7jDQBCcY .section3{fill:#fff;opacity:0.2}#mermaid-svg-H3yetaxX7jDQBCcY .sectionTitle0{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .sectionTitle1{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .sectionTitle2{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .sectionTitle3{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-H3yetaxX7jDQBCcY .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .grid path{stroke-width:0}#mermaid-svg-H3yetaxX7jDQBCcY .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-H3yetaxX7jDQBCcY .task{stroke-width:2}#mermaid-svg-H3yetaxX7jDQBCcY .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .taskText:not([font-size]){font-size:11px}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-H3yetaxX7jDQBCcY .task.clickable{cursor:pointer}#mermaid-svg-H3yetaxX7jDQBCcY .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-H3yetaxX7jDQBCcY .taskText0,#mermaid-svg-H3yetaxX7jDQBCcY .taskText1,#mermaid-svg-H3yetaxX7jDQBCcY .taskText2,#mermaid-svg-H3yetaxX7jDQBCcY .taskText3{fill:#fff}#mermaid-svg-H3yetaxX7jDQBCcY .task0,#mermaid-svg-H3yetaxX7jDQBCcY .task1,#mermaid-svg-H3yetaxX7jDQBCcY .task2,#mermaid-svg-H3yetaxX7jDQBCcY .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutside0,#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutside2{fill:#000}#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutside1,#mermaid-svg-H3yetaxX7jDQBCcY .taskTextOutside3{fill:#000}#mermaid-svg-H3yetaxX7jDQBCcY .active0,#mermaid-svg-H3yetaxX7jDQBCcY .active1,#mermaid-svg-H3yetaxX7jDQBCcY .active2,#mermaid-svg-H3yetaxX7jDQBCcY .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-H3yetaxX7jDQBCcY .activeText0,#mermaid-svg-H3yetaxX7jDQBCcY .activeText1,#mermaid-svg-H3yetaxX7jDQBCcY .activeText2,#mermaid-svg-H3yetaxX7jDQBCcY .activeText3{fill:#000 !important}#mermaid-svg-H3yetaxX7jDQBCcY .done0,#mermaid-svg-H3yetaxX7jDQBCcY .done1,#mermaid-svg-H3yetaxX7jDQBCcY .done2,#mermaid-svg-H3yetaxX7jDQBCcY .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-H3yetaxX7jDQBCcY .doneText0,#mermaid-svg-H3yetaxX7jDQBCcY .doneText1,#mermaid-svg-H3yetaxX7jDQBCcY .doneText2,#mermaid-svg-H3yetaxX7jDQBCcY .doneText3{fill:#000 !important}#mermaid-svg-H3yetaxX7jDQBCcY .crit0,#mermaid-svg-H3yetaxX7jDQBCcY .crit1,#mermaid-svg-H3yetaxX7jDQBCcY .crit2,#mermaid-svg-H3yetaxX7jDQBCcY .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-H3yetaxX7jDQBCcY .activeCrit0,#mermaid-svg-H3yetaxX7jDQBCcY .activeCrit1,#mermaid-svg-H3yetaxX7jDQBCcY .activeCrit2,#mermaid-svg-H3yetaxX7jDQBCcY .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-H3yetaxX7jDQBCcY .doneCrit0,#mermaid-svg-H3yetaxX7jDQBCcY .doneCrit1,#mermaid-svg-H3yetaxX7jDQBCcY .doneCrit2,#mermaid-svg-H3yetaxX7jDQBCcY .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-H3yetaxX7jDQBCcY .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-H3yetaxX7jDQBCcY .milestoneText{font-style:italic}#mermaid-svg-H3yetaxX7jDQBCcY .doneCritText0,#mermaid-svg-H3yetaxX7jDQBCcY .doneCritText1,#mermaid-svg-H3yetaxX7jDQBCcY .doneCritText2,#mermaid-svg-H3yetaxX7jDQBCcY .doneCritText3{fill:#000 !important}#mermaid-svg-H3yetaxX7jDQBCcY .activeCritText0,#mermaid-svg-H3yetaxX7jDQBCcY .activeCritText1,#mermaid-svg-H3yetaxX7jDQBCcY .activeCritText2,#mermaid-svg-H3yetaxX7jDQBCcY .activeCritText3{fill:#000 !important}#mermaid-svg-H3yetaxX7jDQBCcY .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-H3yetaxX7jDQBCcY g.classGroup text .title{font-weight:bolder}#mermaid-svg-H3yetaxX7jDQBCcY g.clickable{cursor:pointer}#mermaid-svg-H3yetaxX7jDQBCcY g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-H3yetaxX7jDQBCcY g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-H3yetaxX7jDQBCcY .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-H3yetaxX7jDQBCcY .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-H3yetaxX7jDQBCcY .dashed-line{stroke-dasharray:3}#mermaid-svg-H3yetaxX7jDQBCcY #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY .commit-id,#mermaid-svg-H3yetaxX7jDQBCcY .commit-msg,#mermaid-svg-H3yetaxX7jDQBCcY .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-H3yetaxX7jDQBCcY g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-H3yetaxX7jDQBCcY g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-H3yetaxX7jDQBCcY g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-H3yetaxX7jDQBCcY .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-H3yetaxX7jDQBCcY .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-H3yetaxX7jDQBCcY .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-H3yetaxX7jDQBCcY .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-H3yetaxX7jDQBCcY .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-H3yetaxX7jDQBCcY .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-H3yetaxX7jDQBCcY .edgeLabel text{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-H3yetaxX7jDQBCcY .node circle.state-start{fill:black;stroke:black}#mermaid-svg-H3yetaxX7jDQBCcY .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-H3yetaxX7jDQBCcY #statediagram-barbEnd{fill:#9370db}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-state .divider{stroke:#9370db}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-H3yetaxX7jDQBCcY .note-edge{stroke-dasharray:5}#mermaid-svg-H3yetaxX7jDQBCcY .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-H3yetaxX7jDQBCcY .error-icon{fill:#522}#mermaid-svg-H3yetaxX7jDQBCcY .error-text{fill:#522;stroke:#522}#mermaid-svg-H3yetaxX7jDQBCcY .edge-thickness-normal{stroke-width:2px}#mermaid-svg-H3yetaxX7jDQBCcY .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-H3yetaxX7jDQBCcY .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-H3yetaxX7jDQBCcY .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-H3yetaxX7jDQBCcY .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-H3yetaxX7jDQBCcY .marker{fill:#333}#mermaid-svg-H3yetaxX7jDQBCcY .marker.cross{stroke:#333}
:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}
#mermaid-svg-H3yetaxX7jDQBCcY {
color: rgba(0, 0, 0, 0.75);
font: ;
}陷入内核io_uring_queue_initio_uring_queue_init_params__sys_io_uring_setupsyscallio_uring_setupio_uring_queue_mmapio_uring_mmapmmap函数功能
该函数主要将队列深度以及额外的
flags
参数传递到内核,让内核的io_uring_setup
来初始化io_uring
结构体,同时使用mmap
将在内核中初始化的SQ
、CQ
以及SQEs
映射到用户态初始化时传递的
flags
将影响io_uring
的运行方式:IORING_SETUP_IOPOLL
:开启此选项必须保证后续只用O_DIRECT
打开文件并且文件系统的file_operations
中注册了iopoll
函数,否则 IO 将下发失败。开启后内核将调用注册的iopoll
函数来主动轮询设备驱动确认 IO 是否完成,iopoll
的触发时机可以参看 io_uring 内核源码分析IORING_SETUP_SQPOLL
:将启动一个单独的内核线程io_sq_thread
,内核将主动轮询 SQ,然后将 IO 下发至驱动设备,能大大减少提交 IO 时的系统调用开销(内核线程工作时,提交 IO 将无需系统调用;但是该线程可能会休眠,休眠时需要系统调用来唤醒该线程)IORING_SETUP_SQ_AFF
:当IORING_SETUP_SQPOLL
已经配置后,启用sq_thread_cpu
字段,用于配置内核线程io_sq_thread
的跑在哪个 CPU 上
io_uring_get_sqe
由于 SQ 已经通过 mmap
映射到用户态,该函数只需在读取 sq->khead
时通过 io_uring_smp_load_acquire
保证一致性,而 sq->sqe_tail
只用于用户态,直接读取即可,根据 sq->khead
以及 sq->sqe_tail
判断 SQ 是否已满,未满则给出 sq->sqe_tail
处的 sqe
即可,然后更新 sq->sqe_tail
io_uring_prep_#OP
通过调用 io_uring_prep_rw
对 sqe
填充命令 OP、fd
、buffer 指针以及 offset 信息等
io_uring_sqe_set_data
直接对 sqe->user_data
进行赋值
io_uring_submit
函数调用逻辑
#mermaid-svg-6eybk07pJhFDdbaU .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-6eybk07pJhFDdbaU .label text{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .node rect,#mermaid-svg-6eybk07pJhFDdbaU .node circle,#mermaid-svg-6eybk07pJhFDdbaU .node ellipse,#mermaid-svg-6eybk07pJhFDdbaU .node polygon,#mermaid-svg-6eybk07pJhFDdbaU .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-6eybk07pJhFDdbaU .node .label{text-align:center;fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .node.clickable{cursor:pointer}#mermaid-svg-6eybk07pJhFDdbaU .arrowheadPath{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-6eybk07pJhFDdbaU .flowchart-link{stroke:#333;fill:none}#mermaid-svg-6eybk07pJhFDdbaU .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-6eybk07pJhFDdbaU .edgeLabel rect{opacity:0.9}#mermaid-svg-6eybk07pJhFDdbaU .edgeLabel span{color:#333}#mermaid-svg-6eybk07pJhFDdbaU .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-6eybk07pJhFDdbaU .cluster text{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-6eybk07pJhFDdbaU .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-6eybk07pJhFDdbaU text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-6eybk07pJhFDdbaU .actor-line{stroke:grey}#mermaid-svg-6eybk07pJhFDdbaU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-6eybk07pJhFDdbaU .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-6eybk07pJhFDdbaU #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-6eybk07pJhFDdbaU .sequenceNumber{fill:#fff}#mermaid-svg-6eybk07pJhFDdbaU #sequencenumber{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU #crosshead path{fill:#333;stroke:#333}#mermaid-svg-6eybk07pJhFDdbaU .messageText{fill:#333;stroke:#333}#mermaid-svg-6eybk07pJhFDdbaU .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-6eybk07pJhFDdbaU .labelText,#mermaid-svg-6eybk07pJhFDdbaU .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-6eybk07pJhFDdbaU .loopText,#mermaid-svg-6eybk07pJhFDdbaU .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-6eybk07pJhFDdbaU .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-6eybk07pJhFDdbaU .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-6eybk07pJhFDdbaU .noteText,#mermaid-svg-6eybk07pJhFDdbaU .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-6eybk07pJhFDdbaU .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-6eybk07pJhFDdbaU .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-6eybk07pJhFDdbaU .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-6eybk07pJhFDdbaU .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .section{stroke:none;opacity:0.2}#mermaid-svg-6eybk07pJhFDdbaU .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-6eybk07pJhFDdbaU .section2{fill:#fff400}#mermaid-svg-6eybk07pJhFDdbaU .section1,#mermaid-svg-6eybk07pJhFDdbaU .section3{fill:#fff;opacity:0.2}#mermaid-svg-6eybk07pJhFDdbaU .sectionTitle0{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .sectionTitle1{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .sectionTitle2{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .sectionTitle3{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-6eybk07pJhFDdbaU .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .grid path{stroke-width:0}#mermaid-svg-6eybk07pJhFDdbaU .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-6eybk07pJhFDdbaU .task{stroke-width:2}#mermaid-svg-6eybk07pJhFDdbaU .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .taskText:not([font-size]){font-size:11px}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-6eybk07pJhFDdbaU .task.clickable{cursor:pointer}#mermaid-svg-6eybk07pJhFDdbaU .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-6eybk07pJhFDdbaU .taskText0,#mermaid-svg-6eybk07pJhFDdbaU .taskText1,#mermaid-svg-6eybk07pJhFDdbaU .taskText2,#mermaid-svg-6eybk07pJhFDdbaU .taskText3{fill:#fff}#mermaid-svg-6eybk07pJhFDdbaU .task0,#mermaid-svg-6eybk07pJhFDdbaU .task1,#mermaid-svg-6eybk07pJhFDdbaU .task2,#mermaid-svg-6eybk07pJhFDdbaU .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutside0,#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutside2{fill:#000}#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutside1,#mermaid-svg-6eybk07pJhFDdbaU .taskTextOutside3{fill:#000}#mermaid-svg-6eybk07pJhFDdbaU .active0,#mermaid-svg-6eybk07pJhFDdbaU .active1,#mermaid-svg-6eybk07pJhFDdbaU .active2,#mermaid-svg-6eybk07pJhFDdbaU .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-6eybk07pJhFDdbaU .activeText0,#mermaid-svg-6eybk07pJhFDdbaU .activeText1,#mermaid-svg-6eybk07pJhFDdbaU .activeText2,#mermaid-svg-6eybk07pJhFDdbaU .activeText3{fill:#000 !important}#mermaid-svg-6eybk07pJhFDdbaU .done0,#mermaid-svg-6eybk07pJhFDdbaU .done1,#mermaid-svg-6eybk07pJhFDdbaU .done2,#mermaid-svg-6eybk07pJhFDdbaU .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-6eybk07pJhFDdbaU .doneText0,#mermaid-svg-6eybk07pJhFDdbaU .doneText1,#mermaid-svg-6eybk07pJhFDdbaU .doneText2,#mermaid-svg-6eybk07pJhFDdbaU .doneText3{fill:#000 !important}#mermaid-svg-6eybk07pJhFDdbaU .crit0,#mermaid-svg-6eybk07pJhFDdbaU .crit1,#mermaid-svg-6eybk07pJhFDdbaU .crit2,#mermaid-svg-6eybk07pJhFDdbaU .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-6eybk07pJhFDdbaU .activeCrit0,#mermaid-svg-6eybk07pJhFDdbaU .activeCrit1,#mermaid-svg-6eybk07pJhFDdbaU .activeCrit2,#mermaid-svg-6eybk07pJhFDdbaU .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-6eybk07pJhFDdbaU .doneCrit0,#mermaid-svg-6eybk07pJhFDdbaU .doneCrit1,#mermaid-svg-6eybk07pJhFDdbaU .doneCrit2,#mermaid-svg-6eybk07pJhFDdbaU .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-6eybk07pJhFDdbaU .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-6eybk07pJhFDdbaU .milestoneText{font-style:italic}#mermaid-svg-6eybk07pJhFDdbaU .doneCritText0,#mermaid-svg-6eybk07pJhFDdbaU .doneCritText1,#mermaid-svg-6eybk07pJhFDdbaU .doneCritText2,#mermaid-svg-6eybk07pJhFDdbaU .doneCritText3{fill:#000 !important}#mermaid-svg-6eybk07pJhFDdbaU .activeCritText0,#mermaid-svg-6eybk07pJhFDdbaU .activeCritText1,#mermaid-svg-6eybk07pJhFDdbaU .activeCritText2,#mermaid-svg-6eybk07pJhFDdbaU .activeCritText3{fill:#000 !important}#mermaid-svg-6eybk07pJhFDdbaU .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-6eybk07pJhFDdbaU g.classGroup text .title{font-weight:bolder}#mermaid-svg-6eybk07pJhFDdbaU g.clickable{cursor:pointer}#mermaid-svg-6eybk07pJhFDdbaU g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-6eybk07pJhFDdbaU g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-6eybk07pJhFDdbaU .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-6eybk07pJhFDdbaU .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-6eybk07pJhFDdbaU .dashed-line{stroke-dasharray:3}#mermaid-svg-6eybk07pJhFDdbaU #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU .commit-id,#mermaid-svg-6eybk07pJhFDdbaU .commit-msg,#mermaid-svg-6eybk07pJhFDdbaU .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-6eybk07pJhFDdbaU g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-6eybk07pJhFDdbaU g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-6eybk07pJhFDdbaU g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-6eybk07pJhFDdbaU .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-6eybk07pJhFDdbaU .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-6eybk07pJhFDdbaU .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-6eybk07pJhFDdbaU .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-6eybk07pJhFDdbaU .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-6eybk07pJhFDdbaU .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-6eybk07pJhFDdbaU .edgeLabel text{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-6eybk07pJhFDdbaU .node circle.state-start{fill:black;stroke:black}#mermaid-svg-6eybk07pJhFDdbaU .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-6eybk07pJhFDdbaU #statediagram-barbEnd{fill:#9370db}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-state .divider{stroke:#9370db}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-6eybk07pJhFDdbaU .note-edge{stroke-dasharray:5}#mermaid-svg-6eybk07pJhFDdbaU .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-6eybk07pJhFDdbaU .error-icon{fill:#522}#mermaid-svg-6eybk07pJhFDdbaU .error-text{fill:#522;stroke:#522}#mermaid-svg-6eybk07pJhFDdbaU .edge-thickness-normal{stroke-width:2px}#mermaid-svg-6eybk07pJhFDdbaU .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-6eybk07pJhFDdbaU .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-6eybk07pJhFDdbaU .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-6eybk07pJhFDdbaU .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-6eybk07pJhFDdbaU .marker{fill:#333}#mermaid-svg-6eybk07pJhFDdbaU .marker.cross{stroke:#333}
:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}
#mermaid-svg-6eybk07pJhFDdbaU {
color: rgba(0, 0, 0, 0.75);
font: ;
}陷入内核io_uring_submit__io_uring_submit_and_wait__io_uring_flush_sq__io_uring_submitsq_ring_needs_enter__sys_io_uring_enter__sys_io_uring_enter2syscallio_uring_enter函数功能
__io_uring_flush_sq
根据
sq->sqe_tail
、sq->sqe_head
差值依次填充sq->array
,然后一次性更新sq->ktail
,并返回内核中仍未处理sqe
数量(sq->ktail - sq->khead
)sq_ring_needs_enter
判断内核线程
io_sq_thread
是否启用以及正常工作(没有休眠):- 首先要判断用户态
ring->flags
是否配置了IORING_SETUP_SQPOLL
标志位,判断是否启用了内核线程io_sq_thread
- 然后再判断内核态
ring->sq.kflags
是否配置了IORING_SQ_NEED_WAKEUP
标志位,判断内核线程io_sq_thread
是否需要唤醒
当内核线程
io_sq_thread
启用并且正常工作时,则整个io_uring_submit
到此结束,无需后续的__sys_io_uring_enter
系统调用,减少了 IO 下发的系统调用的开销- 首先要判断用户态
__sys_io_uring_enter
系统调用陷入内核态,将参数传递给内核的
io_uring_setup
函数,主要用于提交 IO 和获取 IO 完成情况,具体功能和初始化时配置的ring->flags
相关,详细分析可以参看 io_uring 内核源码分析
io_uring_wait_cqe
在用户态轮询判断是否有一个新的 cqe
,无需系统调用陷入内核,但是会阻塞当前线程直到有一个新的 cqe
或者出错
io_uring_peek_cqe
仅在用户态判断一次是否有新的 cqe
,无需系统调用陷入内核,如果没有新的 cqe
,会返回失败信息 -errno
io_uring_cqe_get_data
cqe->user_data
会在 IO 完成后,从 sqe
复制到对应的 cqe
中,该函数只用直接对 cqe->user_data
进行读取
io_uring_cqe_seen
更新 cq->khead
,避免当前 cqe
被重复获取
io_uring_queue_exit
首先通过 munmap
将初始化时 mmap
的 SQ
、CQ
以及 SQEs
解除映射,然后通过 close
关闭 io_uring
对应的 fd
,close
会调用到该 fd
注册的 io_uring_release
来释放 io_uring
参考资料
本文作者: ywang_wnlo
本文链接: https://ywang-wnlo.github.io/posts/d7259d1d.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
【io_uring】liburing 用户库源码分析的更多相关文章
- cJSON库源码分析
本文采用以下协议进行授权: 自由转载-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. cJSON是一个超轻巧,携带方便,单文件,简单的可以作为A ...
- laravel5.5用户认证源码分析
目录 1. 生成相关文件和配置 2. 分析路由文件 3. 以登陆开始为例,分析auth到底是怎么工作的 3.1 分析登录文件 3.2 分析门面Auth. 1. 生成相关文件和配置 快速生成命令 php ...
- Redis网络库源码分析(1)之介绍篇
一.前言 Redis网络库是一个单线程EPOLL模型的网络库,和Memcached使用的libevent相比,它没有那么庞大,代码一共2000多行,因此比较容易分析.其实网上已经有非常多有关这个网络库 ...
- springBoot集成Redis遇到的坑(择库)源码分析为什么择库失败
提示: springboot提供了一套链接redis的api,也就是个jar包,用到的连接类叫做LettuceConnectionConfiguration,所以我们引入pom时是这样的 <de ...
- 经典iOS第三方库源码分析 - YYModel
YYModel介绍 YYModel是一个针对iOS/OSX平台的高性能的Model解析库,是属于YYKit的一个组件,创建是ibireme. 其实在YYModel出现之前,已经有非常多的Model解析 ...
- AspNetCore.AsyncInitialization库源码分析
AspNetCore.AsyncInitialization 这个库是用来实现在asp.net core应用程序启动时异步执行异步任务.可参考:如何在ASP.NET Core程序启动时运行异步任务(2 ...
- Redis事件库源码分析
由于老大在新项目中使用redis的事件库代替了libevent,我也趁着机会读了一遍redis的事件库代码,第一次读到“优美,让人愉快”的代码,加之用xmind制作的类图非常帅,所以留文纪念. Red ...
- Redis网络库源码分析(3)之ae.c
一.aeCreateEventLoop & aeCreateFileEvent 上一篇文章中,我们已经将服务器启动,只是其中有些细节我们跳过了,比如aeCreateEventLoop函数到底做 ...
- Redis网络库源码分析(2)之启动服务器
一.从main开始 main函数定义在server.c中,它的内容如下: //server.c int main() { signal(SIGPIPE, SIG_IGN); //忽略SIGPIPE信号 ...
- Redis 专栏(使用介绍、源码分析、常见问题...)
一.介绍相关 说Redis : 介绍Redis特性,使用场景,使用Jedis操作Redis等. 二.源码分析 1. 数据结构 Redis源码分析(sds):Redis自己封装的C语言字符串类型. Re ...
随机推荐
- 2021-12-09:二叉树展开为链表。 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左
2021-12-09:二叉树展开为链表. 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左 ...
- Golang指针隐式间接引用
1.Golang指针 在介绍Golang指针隐式间接引用前,先简单说下Go 语言的指针 (Pointer),一个指针可以指向任何一个值的内存地址 它指向那个值的内存地址,在 32 位机器上占用 4 个 ...
- PostgreSQL一站式插件推荐 -- pg_enterprise_views
近日发现PG官方插件列表中新收录了一款插件 pg_enterprise_views,因为官方已经数年未添新的插件了很是新奇,找了台设备测试过后果断上了生产,得空分享给大家. 该插件提供了数十张系统表及 ...
- windows下搭建docker容器环境
下载Docker Desktop https://www.docker.com/ 安装Docker Desktop(软件默认安装c盘,若要安装到其他盘,在安装之前创建软连接再进行安装) 在自定义磁盘中 ...
- .Net后台调用js,提示、打开新窗体、关闭当前窗体
.Net后台调用js,提示.关闭当前窗体.打开新窗体 Response.Write("<script>window.alert('支付成功!');window.open('/Jk ...
- Java中的三元运算,以后用得到!
前言 Java 中的三元运算,平时也叫做三目运算,大家了解吗?下面就详细介绍一下,以后在项目编程中用得到. 一.Java运算符 在最底层,Java 中的数据是通过使用运算符来操作的.运算符是一种特殊的 ...
- 19.详解AQS家族的成员:CountDownLatch
关注王有志,一个分享硬核Java技术的互金摸鱼侠 欢迎你加入Java人的提桶跑路群:共同富裕的Java人 今天我们来聊一聊AQS家族中的另一个重要成员CountDownLatch.关于CountDow ...
- 3 大数据实战系列-spark shell分析日志
1 准备数据源 文件格式: 访问时间\t用户ID\t[查询词]\t该URL在返回结果中的排名\t用户点击的顺序号\t用户点击URL 数据文件越大越好,至少100万行 2 启动任务 ./spark-sh ...
- 一份保姆级的Stable Diffusion部署教程,开启你的炼丹之路
市面上有很多可以被用于AI绘画的应用,例如DALL-E.Midjourney.NovelAI等,他们的大部分都依托云端服务器运行,一部分还需要支付会员费用来购买更多出图的额度.在2022年8月,一款叫 ...
- 【调制解调】SSB 单边带调幅
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录,代码已上传到 Github - ModulationAndDemodulation.本篇介绍 SS ...