簡體   English   中英

僅在需要時運行的Posix pthread worker

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM