Threads vs. fork()

Calling fork() when having multiple threads

當 multi-thread process 呼叫 fork() 時,只有呼叫 fork 的那個 thread 會被複製到 child process 繼續執行

Problem

parent process 的其他 thread 可能持有 mutex 之類的,這樣到了 child process 就會造成這個 mutex 永遠不會解開

Solution

Solution 1: exec()

在 child process 呼叫 exec() 就可以直接覆蓋 parent process 的所有資訊了

Solution 2: use pthread_atfork()

使用 pthread_atfork() 函數註冊三個 callback 函數:

  • prepare:在父 process 呼叫 fork() 之前執行,通常用來取得所有必要的 locks
  • parent:在父 process 中,fork() 建立子 process 之後返回之前執行,通常用來釋放 locks
  • child:在子 process 中,fork() 返回之前執行,通常也用來釋放 locks

在 prepare 取得所有 lock,在 parent 和 child 分別在兩個 process 放掉所有 lock

範例:

pthread_mutex_t lock_A, lock_B;
 
void prepare_handler() {
    pthread_mutex_lock(&lock_A);  // 先鎖住 A
    pthread_mutex_lock(&lock_B);  // 再鎖住 B
}
 
void parent_handler() {
    pthread_mutex_unlock(&lock_B);  // 反向解鎖 B
    pthread_mutex_unlock(&lock_A);  // 反向解鎖 A
}
 
void child_handler() {
    pthread_mutex_unlock(&lock_B);  // 反向解鎖 B
    pthread_mutex_unlock(&lock_A);  // 反向解鎖 A
}
 
pthread_atfork(prepare_handler, parent_handler, child_handler);