Artikel ini akan memperkenalkan anda kepada acara fail dalam Redis Ia mempunyai nilai rujukan tertentu. Saya harap ia dapat membantu anda.
Pelayan Redis ialah program dipacu acara, dibahagikan kepada 文件事件
dan 时间事件
[Cadangan berkaitan: Tutorial video Redis]
Kesemuanya dirangkumkan ke dalam struktur aeEventLoop
typedef struct aeEventLoop { int stop; // 标识事件是否结束 aeFileEvent *events; // 文件事件数组,存储已注册的文件事件 aeFireEvent *fired; // 存储被触发的文件事件 aeTimeEvent *timteEventHead; // 多个时间事件形成的链表 void *apidata; // I/O模型的封装 aeBeforeSleepProc *beforesleep; // 进程阻塞前执行 aeBeforeSleepProc *aftersleep; // 进程被唤醒后执行 } aeEventLoop;
Pemandu acara sebenarnya menggelung melalui gelung while/for
, menunggu acara berlaku
while (! eventLoop->stop) { if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop) aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP); }
aeProcessEvents
Fungsi utama untuk pemprosesan acara
Klien Redis berinteraksi dengan pelayan melalui soket TCP merujuk kepada peristiwa boleh dibaca dan boleh ditulis soket. Secara amnya, mod tidak menyekat digunakan dan pemultipleksan I/O yang berkaitan termasuk select/epoll/kqueue
, dsb. Sistem pengendalian yang berbeza mempunyai pelaksanaan yang berbeza.
Ambil epoll
sebagai contoh, ia adalah penyelesaian yang dicadangkan oleh kernel Linux untuk mengendalikan sejumlah besar sambungan rangkaian serentak. epoll
Sediakan 3 API
epoll_create mencipta deskriptor fail khusus epoll untuk panggilan API berkaitan epoll berikutnya
int epoll_create(int size) // size 告知内核程序期望注册的网络连接数目,Linux 2.6.8后改为内核动态分配 // 返回参数是 epoll 专用的文件描述符
Fungsi epoll_ctl mendaftar, mengubah suai atau memadam acara yang perlu dipantau dengan epoll
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) // epfd 函数 epoll_create 返回的 epoll 文件描述符 // op 操作类型 EPOLL_CTL_ADD:注册事件; EPOLL_CTL_MOD:修改网络连接事件; EPOLL_CTL_DEL:删除事件 // fd 网络连接的 socket 文件描述符 // event 需要监控的事件
Fungsi epoll_wait akan menyekat proses sehingga pemantauan Beberapa sambungan rangkaian mempunyai acara
int epoll_wait(int epfd, struct epoll_event *event, int maxevents, int timeout) // epfd 函数epoll_create返回的epoll文件描述符 // epoll_event 作为输出参数使用,用于回传已触发的事件数组 // maxevents 每次能处理的最大事件数目 // timeout epoll_wait 函数阻塞超时时间,如果超过 timeout 时间还没有事件发生,函数就不再阻塞直接返回;当 timeout 等于0是函数立即返回,timeout 等于-1时函数一直阻塞到有事件发生
Reids tidak secara langsung menggunakan API epoll, tetapi menyokong 4 jenis pada masa yang sama model pemultipleksan I/O masa merangkum API model ini. Kemudian semasa fasa penyusunan, model pemultipleksan I/O yang disokong oleh sistem pengendalian disemak, dan model mana yang diputuskan untuk digunakan semula mengikut strategi.
Mengambil epoll sebagai contoh, Redis dirangkumkan seperti berikut
// 对应 epoll_create static int aeApiCreate(aeEventLoop *eventLoop) // 对应 epoll_ctl 添加事件 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) // 对应 epoll_ctl 删除事件 static int aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) // 对应 epoll_wait static int aeApiPool(aeEventLoop *eventLoop, struct timeval *tvp)
Imbas kembali struktur eventLoop
yang dinyatakan di atas, apidata ahlinya menunjuk kepada 4 jenis pemultipleksan I/O Gunakan objek model ; peristiwa menyimpan tatasusunan acara yang perlu dipantau, dan menggunakan deskriptor fail soket sebagai indeks tatasusunan untuk mengakses elemen yang dipecat menyimpan tatasusunan acara yang dicetuskan.
Struktur acara fail ditakrifkan seperti berikut:
typedef struct aeFileEvent { int mask; // 文件事件类型 AE_READABLE 可读事件;AE_WRITEABLE 可写事件 aeFileProc *rfileProc; // 读事件处理函数指针 aeFileProc *wfileProc; // 写事件处理函数指针 void *clientData; // 指向对应的客户端对象 } aeFileEvent;
Lihat pelaksanaan acara fail cipta aeCreateFileEvent
int aeCreateFileEvent (aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) { aeFileEvent *fe = &eventLoop->evnts[fd]; if (aeApiAddEvent(eventLoop, fd, mask) == -1) return AE_ERR; fe->mask |= mask; if (mask & AE_READABLE) fe->rfileProc = proc; if (mask & AE_WRITABLE) fe->wfileProc = proc; fe->clientData = clientData; return AE_OK; }
Pelayan Redis akan mencipta pelbagai acara fail. Memproses transaksi, seperti:
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler, NULL);
aeCreateFileEvent(server.el, fd, AE_READABLLE, readQueryFromClient, c);
aeCreateFileEvent(server.el, c->fd, AE_READABLLE, sendReplyToClient, c);
Pelaksanaan semua acara Redis dikawal dengan fungsi aeProcessEvents
. Antaranya, pelaksanaan peristiwa fail akan menyebabkan penyekatan (epoll_wait Jika peristiwa penyekatan terlalu lama, ia akan menghalang pelaksanaan peristiwa masa (masa Untuk mengelakkan situasi ini, masa menunggu berlalu apabila melaksanakan acara fail). Ia diperoleh dengan mengira peristiwa masa terawal yang berlaku
int aeProcessEvents(aeEventLoop *eventLoop, int flags) { shortest = aeSearchNearestTimer(eventLoop); long long ms = (shortest->when_sec - now_sec) * 1000 + \ shortest->when_ms - now_ms; // 阻塞事件发生 numevents = aeApiPoll(eventLoop, ms); for (j=0; j < numevents; j++) { aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j]].fd]; // 处理文件事件,即根据类型执行rfileProc或wfileProc } // 处理时间事件 processed += processTimeEvents(eventLoop); }
Sekarang mari kita lihat secara keseluruhan proses arahan sepadan pelayan Redis
jadual fungsi aeMain dan melaksanakan acara fail dan acara masa dengan memanggil fungsi aeProcessEvents. Maklumat berkaitan acara direkodkan dalam aeEventLoop. Mula-mula, dapatkan selang masa pelaksanaan n peristiwa masa terpendek melalui fungsi aeSearchNearestTimer, kemudian panggil fungsi aeApiPoll untuk mendapatkan soket yang dipantau, dan akhirnya laksanakan fungsi pemprosesan acara rfileProc dan wfileProc yang sepadan dengan soket, dan akhirnya laksanakan acara masa fungsi processTimeEvents .
Acara sambungan pelanggan-pelayan yang lengkap:
Pelayan mendengar acara AE_READABLE perkataan pakej Apabila pelanggan menghantar permintaan sambungan dan menghasilkan acara AE_READABLE , pelayan akan Menjawab permintaan sambungan klien, menggabungkan acara AE_READABLE soket klien dengan fungsi pemprosesan permintaan arahan (aeFileProc), dan klien boleh menghantar permintaan arahan ke pelayan
hujung ke hujung Pelayan menghantar permintaan arahan, dan soket klien akan menjana peristiwa AE_READABLE, mencetuskan pemproses arahan untuk melaksanakan perintah akan menghasilkan balasan arahan yang sepadan soket klien dengan fungsi pemprosesan balasan arahan ( aeFileProc) yang dikaitkan dengan
apabila cuba membaca balasan arahan, soket klien akan menjana peristiwa AE_WRITABLE, mencetuskan pelaksanaan pemproses balasan arahan . Apabila pemproses balasan arahan menulis semua balasan arahan Selepas memasuki soket, pelayan akan menghubungi perkaitan antara acara AE_WRITABLE soket klien dan fungsi pemprosesan balasan arahan (aeFileProc)
Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati: Video Pengaturcaraan! !
Atas ialah kandungan terperinci Artikel untuk membincangkan tentang epoll dan acara fail dalam Redis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!