2017-01-23 66 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返回后,您的句柄指向任何内容。