真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

nodejs中怎么創(chuàng)建線程

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

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的永濟(jì)網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!


   當(dāng)我們調(diào)用new Worker的時候,最后會調(diào)用c++的StartThread函數(shù)(node_worker.cc)創(chuàng)建一個線程。

CHECK_EQ(uv_thread_create_ex(&w->tid_, &thread_options, [](void* arg) {
    // ...
  }, static_cast(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。表示報(bào)錯。我們回頭看一下返回非0時,c++的處理。我們對c++層的CHECK_EQ(uv_thread_create_ex(…), 0)進(jìn)行宏展開。

#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)
 

因?yàn)閯?chuàng)建線程時返回非0,所以這里是true。我們繼續(xù)看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)
 

拼接錯誤信息,然后執(zhí)行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();
}
 

重點(diǎn)是Abort,

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

繼續(xù)看ABORT_NO_BACKTRACE

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

所以最終調(diào)用的是_exit或abort退出或者終止進(jìn)程。我們討論linux下的情況。我們看abort函數(shù)的說明

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函數(shù)會給進(jìn)程發(fā)送SIGABRT信號,我們可以注冊函數(shù)處理這個信號,不過我們還是無法阻止進(jìn)程的退出,因?yàn)樗麍?zhí)行完我們的處理函數(shù)后,會把處理函數(shù)注冊為系統(tǒng)的默認(rèn)的,然后再次發(fā)送SIGABRT信號,而默認(rèn)的行為就是終止進(jìn)程。我們來個測試。

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

我們創(chuàng)建1000個線程。結(jié)果

nodejs中怎么創(chuàng)建線程  

 
nodejs中怎么創(chuàng)建線程  

看完上述內(nèi)容,你們掌握nodejs中怎么創(chuàng)建線程的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


分享文章:nodejs中怎么創(chuàng)建線程
網(wǎng)站路徑:http://weahome.cn/article/jsieop.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部