Thread-Safe and Re-entrancy === 這篇起源自前一場面試,因為筆者這個嘴砲性格,遇到不如意總會說個幾句 於是有這篇詳述當場面試官的「錯誤」 一句話概括這個標題:「不是所有 thread-safe 都是 reentrant」,千萬不要誤把 thread-safe 就當作 reentrance。 - 前情背景 - 會讓筆者下定決心寫這邊部落格,除了面試官觀念錯誤之外,還對筆者**搖頭嘆氣**。 - 其實以前就有寫過[文章](https://hackmd.io/@25077667/Hky5QyIXu),但當時沒有寫好重寫會更好。 ## 定義 Reentrancy: - The function executed by the same thread, or simultaneously executed by another thread and still correctly complete the original execution. - 註:C++ 標準對 reentrancy 的定義並不 formal: [§16.4.6.9](https://eel.is/c++draft/reentrancy) - [Dictionary](https://dictionary.cambridge.org/dictionary/english-chinese-traditional/re-entrant) - Able to be run on several processors at the same time and be interrupted and called again without affecting what is happening on the other processors. Thread-safe: - Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. ## 四個例子 ### Thread-Safe and Reentrant ```cpp unsigned long long fib(unsigned long long index) { if (!index) return 0; else if (index == 1 || index == 2) return 1; return fib(index - 1) + fib(index - 2); } ``` ### Not Thread-Safe and Reentrant ```cpp static int data = 0; int foo() { data++; return 42; } ``` 這邊需要注意到,reentrancy 保證到的是重入執行結果的正確性,但不會保證中間過程的狀態。 其他只能說是總結 reentrancy 的常見屬性,不是 reentrancy 的 requirements. ### Thread-Safe and Not Reentrant ```cpp void write_file(const std::string &filename, const std::vector<char> data) { static std::mutex m_; std::lock_guard<std::mutex> lock(m_); auto ofs = std::ofstream(filename, std::ios::out | std::ios::binary); for (const auto& byte : data) ofs << byte; } ``` ### Not Thread-Safe and Not Reentrant ```cpp static int g_data; void write_file(const std::string &filename, const std::vector<char> data) { g_data++; // manipulate the g_data static std::mutex m_; std::lock_guard<std::mutex> lock(m_); auto ofs = std::ofstream(filename, std::ios::out | std::ios::binary); for (const auto& byte : data) ofs << byte; } ``` ![](https://hackmd.io/_uploads/Syns0x7xa.png)