2017-01-23 67 views
0

我正在處理一個項目,該項目需要我使用void指針存儲對pthread的所有引用,並使用包裝函數創建並取消這些線程。pthread_cancel()在傳入類型轉換void pointer時不起作用

因此我結束了以下內容:

typedef void * ThreadHandle_t; 

void * endlessWhileLoop(void * p){ 
    while(1); 
} 

int createThread(ThreadHandle_t * handle){ 
    pthread_t thread; 
    int ret = pthread_create(&(thread), NULL, endlessWhileLoop, NULL); 
    if (ret != 0) { 
     return -1; 
    } 

    /* Configure the ThreadHandle to point to the task */ 
    if (handle != NULL) { /* If handle was passed in */ 
     *handle = &thread; 
    } 
    //ret = pthread_cancel(*(pthread_t *)*handle); <--This works 

    return ret; 

} 

int deleteThread(ThreadHandle_t handle){ 
    int ret = pthread_cancel(*(pthread_t *)handle); 

    if(ret != 0){ 
     printf("Failed to delete task, return code: %d", ret); 
     return -1; 
    } 

    return ret; 
} 

int main(void){ 
    ThreadHandle_t temp = 0; 
    createThread(&temp); 
    deleteThread(temp); 
} 

不過,我收到找不到錯誤在deleteThread的cancel_thread調用線程。

如果我將pthread_cancel調用轉移到createThread函數中,即使在使用ThreadHandle的情況下,它也可以工作,並且線程被取消。

難道我沒有通過正確的引用傳遞使用ThreadHandle_t的pthread_t嗎?我很迷惑......

+1

你的邏輯真的沒有任何意義。由於'temp'是一個指向void的指針,你將不得不使用它來指向'pthread_t'。但是你在哪裏分配任何'pthread_t'來指向? –

回答

4

這裏有一個很大的問題(從createThread功能):

pthread_t thread; 
... 
*handle = &thread; 

在這裏你做出*handle指向當地變量thread。但請記住,函數返回時,thread將超出範圍,並且指針將不再有效。這會導致未定義的行爲當您稍後嘗試使用此無效指針時。

我的建議是跳過ThreadHandle_t類型,並簡單地從createThread函數中返回pthread_t(不是指針),並將其傳遞給需要它的函數。

+0

啊,當然!謝謝。不幸的是,createThread函數不能返回pthread,因爲我正在嘗試使用這些相同的函數將某些東西移植到另一個平臺。我認爲最好的辦法是將ThreadHandle_t作爲pthread來代替void指針。 –

2

您的pthread是createThread中的局部變量。這是錯誤的。使其成爲全局或在主要功能中定義。

createThread返回後,您的句柄指向任何內容。