中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

nodejs中怎么創建線程

發布時間:2021-07-08 16:09:39 來源:億速云 閱讀:358 作者:Leah 欄目:大數據

nodejs中怎么創建線程,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。


   當我們調用new Worker的時候,最后會調用c++的StartThread函數(node_worker.cc)創建一個線程。

CHECK_EQ(uv_thread_create_ex(&w->tid_, &thread_options, [](void* arg) {
    // ...
  }, static_cast<void*>(w)), 0);
 

我們看uv_thread_create_ex的邏輯

int uv_thread_create_ex(uv_thread_t* tid,
                        const uv_thread_options_t* params,
                        void (*entry)(void *arg),
                        void *arg) {
  // 忽略部分代碼
  err = pthread_create(tid, attr, f.out, arg);
  return UV__ERR(err);
}
 

接著我們看一下pthread_create的返回值定義

On success, pthread_create() returns 0; on error, it returns an error
      number, and the contents of *thread are undefined.

所以,如果uv_thread_create_ex返回非0,即pthread_create返回非0。表示報錯。我們回頭看一下返回非0時,c++的處理。我們對c++層的CHECK_EQ(uv_thread_create_ex(…), 0)進行宏展開。

#define CHECK_EQ(a, b) CHECK((a) == (b))

#define CHECK(expr)                                                           \
  do {                                                                        \
    if (UNLIKELY(!(expr))) {                                                  \
      ERROR_AND_ABORT(expr);                                                  \
    }                                                                         \
  } while (0)

#define UNLIKELY(expr) expr
 

通過一些列展開,最后變成

  do {                                                                        
    if (!(返回值 == 0)) {                                                  
      ERROR_AND_ABORT(expr);                                                  
    }                                                                         
  } while (0)
 

因為創建線程時返回非0,所以這里是true。我們繼續看ERROR_AND_ABORT

#define ERROR_AND_ABORT(expr)                                                 \
  do {                                                                
    static const node::AssertionInfo args = {                                 \
      __FILE__ ":" STRINGIFY(__LINE__), #expr, PRETTY_FUNCTION_NAME           \
    };                                                                        \
    node::Assert(args);                                                       \
  } while (0)
 

拼接錯誤信息,然后執行node::Assert(args);

[[noreturn]] void Assert(const AssertionInfo& info) {
  char name[1024];
  GetHumanReadableProcessName(&name);

  fprintf(stderr,
          "%s: %s:%s%s Assertion `%s' failed.\n",
          name,
          info.file_line,
          info.function,
          *info.function ? ":" : "",
          info.message);
  fflush(stderr);

  Abort();
}
 

重點是Abort,

[[noreturn]] void Abort() {
  DumpBacktrace(stderr);
  fflush(stderr);
  ABORT_NO_BACKTRACE();
}
 

繼續看ABORT_NO_BACKTRACE

#ifdef _WIN32
#define ABORT_NO_BACKTRACE() _exit(134)
#else
#define ABORT_NO_BACKTRACE() abort()
#endif
 

所以最終調用的是_exit或abort退出或者終止進程。我們討論linux下的情況。我們看abort函數的說明

The abort() function first unblocks the SIGABRT signal, and then
      raises that signal for the calling process (as though raise(3) was
      called).  This results in the abnormal termination of the process
      unless the SIGABRT signal is caught and the signal handler does not
      return (see longjmp(3)).
      If the SIGABRT signal is ignored, or caught by a handler that
      returns, the abort() function will still terminate the process.  It
      does this by restoring the default disposition for SIGABRT and then
      raising the signal for a second time.

abort函數會給進程發送SIGABRT信號,我們可以注冊函數處理這個信號,不過我們還是無法阻止進程的退出,因為他執行完我們的處理函數后,會把處理函數注冊為系統的默認的,然后再次發送SIGABRT信號,而默認的行為就是終止進程。我們來個測試。

const { Worker, threadId } = require('worker_threads');
for (let i = 0; i < 1000; i++) {
    const worker = new Worker('var a = 1;', { eval: true });
}
 

我們創建1000個線程。結果

nodejs中怎么創建線程  

 
nodejs中怎么創建線程  


看完上述內容,你們掌握nodejs中怎么創建線程的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德阳市| 海丰县| 武宁县| 呼玛县| 家居| 满城县| 南昌县| 惠水县| 福州市| 崇仁县| 邹平县| 琼结县| 栾川县| 鄂州市| 沭阳县| 盐池县| 崇州市| 龙口市| 静海县| 陆川县| 黄骅市| 衡阳市| 盈江县| 马边| 巴林左旗| 丰都县| 大埔区| 苏尼特右旗| 含山县| 广州市| 建水县| 洛川县| 阿拉善左旗| 昆山市| 辽源市| 芜湖县| 阿城市| 安徽省| 克东县| 元朗区| 信宜市|