[英]Posix pthread worker that is only running when needed
我有一個工作線程正在執行輪詢活動(它的目標是libcurl,但這不相關)。
應用程序中的許多操作都可以啟動工作線程,但是如果它已經在運行,則不應創建任何新線程。 來自應用程序的新請求僅與已經進行的任何其他輪詢結合在一起。
總而言之,當沒有任何事情要做時,單個工作線程退出。
代碼是:
pthread_t thread = NULL;
struct timespec sleep_val = {0, 20000000};
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_exit(NULL);
thread = NULL;
}
void start_worker_thread_if_needed() {
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
}
我對線程安全性表示懷疑。 函數start_worker_thread_if_needed()可以在任意時間任意次數調用。
因此,如果在退出while循環並因此中斷工作線程時恰好調用了start_worker_thread_if_needed()會怎樣。 如果發生這種情況,由於工作線程被中斷並且pthread_exit + thread = NULL尚未完成,因此if(thread == NULL)的條件將為FALSE。
因此,現在start_worker_thread_if_needed()將在不創建新線程的情況下退出,但是一旦控制權返回到舊的工作線程,它將繼續進入pthread_exit行,並且工作線程被銷毀。
問題在於,剛剛觸發start_worker_thread_if_needed()的請求將丟失,並且直到下一次調用start_worker_thread_if_needed()時,輪詢才會開始。
編輯:這是與互斥的建議,但我仍然有同樣的疑問。 如果主線程剛在退出while循環之后且工作者可以使用互斥鎖時中斷,會發生什么情況。 然后,主線程不創建新線程,然后工作程序退出。
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_mutex_lock(&my_mutex);
thread = NULL;
pthread_mutex_unlock(&my_mutex);
pthread_exit(NULL);
}
void start_worker_thread_if_needed() {
pthread_mutex_lock(&my_mutex);
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
pthread_mutex_unlock(&my_mutex);
}
我認為我在設置方面存在缺陷,如果有人可以提供適當的解決方案,我們將不勝感激。
感謝以上評論中的所有幫助。 Kaylums建議使用條件變量似乎是避免冒我擔心的極端情況的好方法。
最終的代碼(已刪除日志)是下面的代碼,它似乎可以正常工作。
static int no_of_handles_running;
static int RUN_THREAD = 0;
pthread_t thread = NULL;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;;
void *worker_thread(void *threadid)
{
RUN_THREAD = 1;
do {
poll(); //Will update no_of_handles_running
if (no_of_handles_running == 0) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cv, &mutex);
pthread_mutex_unlock(&mutex);
}
} while (RUN_THREAD);
thread = NULL;
pthread_exit(NULL);
}
void start_worker_thread() {
if (thread == NULL) {
int rc = pthread_create(&thread, NULL, worker_thread, NULL);
if (rc){
return;
}
}
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
void stop_worker_thread() {
RUN_THREAD = 0;
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.