我有一個線程池。 main()函數啓動經典池設置。一個老闆線程和一些工作線程。大部分代碼已完成,但缺少的部分是錯誤處理。捕捉到一個正在退出的線程c
當一個boss/worker線程發生錯誤時,調用pthread_exit()。 main()線程如何知道池中出現錯誤以重新啓動它?
我有一個線程池。 main()函數啓動經典池設置。一個老闆線程和一些工作線程。大部分代碼已完成,但缺少的部分是錯誤處理。捕捉到一個正在退出的線程c
當一個boss/worker線程發生錯誤時,調用pthread_exit()。 main()線程如何知道池中出現錯誤以重新啓動它?
如果你想保存錯誤或恢復信息,或者你想非阻塞功能,可以與相關的互斥一起使用的條件變量,幷包含結構失敗的線程,錯誤和您需要的恢復信息。所有這些變量應該是全球性的。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct error_info err;
在boss線程中,您必須首先初始化err結構,然後鎖定互斥鎖。
pthread_mutex_lock(&mutex);
然後您等待使用pthread_cond_wait發生的情況。
pthread_cond_wait(&cond, &mutex);
條件發生後,處理錯誤,並使用pthread_join從線程獲取返回值。請注意,pthread_cond_wait是阻塞的,如果你想要一個非阻塞版本,你應該使用pthread_cond_timedwait,它具有第三個參數struct timespec *,它保存等待過期的絕對系統時間。最後記得解鎖你的互斥鎖。
pthread_mutex_unlock(&mutex);
在沒有工作線程,退出應先鎖定互斥之前,然後填寫ERR結構,信號老闆線程,解鎖互斥鎖,並退出。要發信號給boss線程,應該使用pthread_cond_signal函數。
pthread_cond_signal(&cond);
您可以使用:
pthread_join(pthread_t child, void**);
讓你的線程的返回值。 pthread_join是一個阻塞函數,它將等待一個線程退出。您可以傳遞參數的pthread_join函數:
void pthread_exit(void *value_ptr);
爲什麼你不讓自己重啓自己而不是退出?這聽起來像一個更清潔的設計... – 2012-01-28 00:41:57
@R ..這是我的想法。在C語言中沒有任何異常可以在線程的外層引發並捕獲,但它應該可以在任務中生成某種錯誤報告,並且可以循環執行另一個錯誤報告。我不得不說,這種事情在C++中更容易... – 2012-01-28 01:00:42
不,如果您調用'pthread_exit',那麼除非您已經使用取消處理程序來展開堆棧並執行清理任務,否則您可以調用'longjmp'回到你開始的地方,而不是調用'pthread_exit'。這只是將'pthread_exit'調用改爲'longjmp'的問題。或者,您可以在調用'pthread_exit'之前調用'pthread_create'並創建一個新線程來替換調用線程。 – 2012-01-28 01:23:30