溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

nodejs中怎么利用close實(shí)現(xiàn)事件循環(huán)

發(fā)布時(shí)間:2021-07-21 09:05:47 來源:億速云 閱讀:135 作者:Leah 欄目:大數(shù)據(jù)

nodejs中怎么利用close實(shí)現(xiàn)事件循環(huán),相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

close是nodejs每輪事件循環(huán)中最后的一個階段。我們看看怎么使用。我們知道對于一個handle,他的使用一般是init,start,stop。但是如果我們在stop一個handle之后,還有些事情需要處理怎么辦?這時(shí)候就可以使用close階段。close階段可以用來關(guān)閉一個handle,并且執(zhí)行一個回調(diào)。比如用于釋放動態(tài)申請的內(nèi)存。close階段的任務(wù)由uv_close產(chǎn)生。

void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
  // 正在關(guān)閉,但是還沒執(zhí)行回調(diào)等后置操作
  handle->flags |= UV_HANDLE_CLOSING;
  handle->close_cb = close_cb;

  switch (handle->type) {

  case UV_PREPARE:
    uv__prepare_close((uv_prepare_t*)handle);
    break;

  case UV_CHECK:
    uv__check_close((uv_check_t*)handle);
    break;
    ...
  default:
    assert(0);
  }

  uv__make_close_pending(handle);
}
 

uv_close設(shè)置回調(diào)和狀態(tài),然后根據(jù)handle類型調(diào)對應(yīng)的close函數(shù),一般就是stop這個handle。比如prepare的close函數(shù)。

void uv__prepare_close(uv_prepare_t* handle) {                           
    uv_prepare_stop(handle);                                                 
}
 

接著執(zhí)行uv__make_close_pending往close隊(duì)列追加節(jié)點(diǎn)。

// 頭插法插入closing隊(duì)列,在closing階段被執(zhí)行
void uv__make_close_pending(uv_handle_t* handle) {
  handle->next_closing = handle->loop->closing_handles;
  handle->loop->closing_handles = handle;
}
 

產(chǎn)生的節(jié)點(diǎn)在closing_handles隊(duì)列中保存,然后在close節(jié)點(diǎn)逐個處理。

// 執(zhí)行closing階段的的回調(diào)
static void uv__run_closing_handles(uv_loop_t* loop) {
  uv_handle_t* p;
  uv_handle_t* q;

  p = loop->closing_handles;
  loop->closing_handles = NULL;

  while (p) {
    q = p->next_closing;
    uv__finish_close(p);
    p = q;
  }
}

// 執(zhí)行closing階段的回調(diào)
static void uv__finish_close(uv_handle_t* handle) {
  handle->flags |= UV_HANDLE_CLOSED;
  ...
  uv__handle_unref(handle);
  QUEUE_REMOVE(&handle->handle_queue);
  if (handle->close_cb) {
    handle->close_cb(handle);
  }
}
 

逐個執(zhí)行回調(diào),close和stop有一點(diǎn)不同的是,stop一個handle,他不會從事件循環(huán)中被移除,但是close一個handle,他會從事件循環(huán)的handle隊(duì)列中移除。
    我們看一個使用了uv_close的例子(省略部分代碼)。

int uv_fs_poll_start(uv_fs_poll_t* handle,
                     uv_fs_poll_cb cb,
                     const char* path,
                     unsigned int interval) {
  struct poll_ctx* ctx;
  // 分配一塊堆內(nèi)存存上下文結(jié)構(gòu)體和path對應(yīng)的字符串
  ctx = uv__calloc(1, sizeof(*ctx) + len);
  // 掛載上下文到handle
  handle->poll_ctx = ctx;

}
 

uv_fs_poll_start是用于監(jiān)聽文件是否有改變的函數(shù)。他在handle里掛載了一個基于堆結(jié)構(gòu)體。當(dāng)結(jié)束監(jiān)聽的時(shí)候,他需要釋放掉這塊內(nèi)存。

// 停止poll
int uv_fs_poll_stop(uv_fs_poll_t* handle) {
  struct poll_ctx* ctx;
  ctx = handle->poll_ctx;
  handle->poll_ctx = NULL;
  uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
}
 

uv_fs_poll_stop通過uv_close函數(shù)關(guān)閉handle,傳的回調(diào)是timer_close_cb。

// 釋放上下文結(jié)構(gòu)體的內(nèi)存
static void timer_close_cb(uv_handle_t* handle) {
  uv__free(container_of(handle, struct poll_ctx, timer_handle));
}
 

所以在close階段就會是否這塊內(nèi)存。

看完上述內(nèi)容,你們掌握nodejs中怎么利用close實(shí)現(xiàn)事件循環(huán)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI