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;
}
```
