【问题标题】:pthread_Join can't return after call pthread_cancel?调用 pthread_cancel 后 pthread_Join 无法返回?
【发布时间】:2012-05-09 05:32:06
【问题描述】:

我使用Eclispse Indigo + CDT 8.0.2 + cygwin 开发了一个多线程系统,代码如下:

pthread_mutex_t mutexCmd = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t signalCmd = PTHREAD_COND_INITIALIZER;

void * Func(void * arg)
{
    int iStatus;
    while (1)
    {
        int a = 1;
        pthread_cleanup_push(pthread_mutex_unlock, &mutexCmd);
        pthread_mutex_lock(&mutexCmd);
        iStatus = pthread_cond_wait(&signalCmd, &mutexCmd);
        if (iStatus) {
                err_abort(iStatus, "signalCmd status error");
        }
        if(arg->Cmd != navi_Go) //Just a command tag;
        {
            pthread_mutex_unlock(&(pNaviCtrl->mutexCmd));
            continue;
        }
        //do some work
        //.....
        pthread_mutex_unlock(&mutexCmd);
        pthread_cleanup_pop(1);
    }
//pthread_detach(pthread_self());
return  NULL;
}

int main()
{
    int iStatus = 0;
    pthread = tid;
     iStatus = pthread_create(&tid;NULL, Func, NULL);
     if(iStatus)
    {
    err_abort(iStatus, "Start pthread error");
    }
    // do some work
    ...
    //Cancel thread
   void * retval;
   iStatus = pthread_cancel(tid) 
   iStatus = pthread_join(tid; &retval);
   if(iStatus){
        err_abort(iStatus,"Stop thread error");
    }
    return iStatus;
}

程序运行的地方,它停在“iStatus = pthread_join(tid1; &retval);”无法继续前进,我认为线程可能会死锁,但找不到原因。我想在调用 pthread_cancel() 之后,线程会退出并返回到 pthread_join(), 谁能告诉我我的代码有什么问题?

【问题讨论】:

  • 我发现当我删除“pthread_cleanup_push”和“pthread_cleanup_pop”时一切正常,但我想知道原因

标签: pthreads


【解决方案1】:

不要将 cleanup_push 和 _pop 放在 while 循环中。不要多次打电话给他们。如果您查看它们,它们是在 { } 中包装它们之间的代码的宏。他们设置了一个 longjump,在您调用 pthread_cancel 时使用。

【讨论】:

    【解决方案2】:

    pthread_cleanup_pop(1) 告诉 pthread 库不仅要从堆栈中弹出清理条目,还要执行它。因此该调用也将隐式调用:

    pthread_mutex_unlock(&mutexCmd);
    

    由于您已经解锁了互斥锁,因此该调用具有未定义的行为(假设互斥锁类型为PTHREAD_MUTEX_NORMAL)。我想那个电话永远不会回来或其他什么。

    请注意,您的代码在处理清理时还有其他问题 - 如果您为循环执行 continue,您将第二次(或更多)调用 pthread_cleanup_push(),这将添加另一个清理上下文。

    可能还有其他问题(我对pthread_cancel()不是很熟悉)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 2016-06-02
      • 2022-10-15
      • 2021-10-26
      • 2020-08-15
      相关资源
      最近更新 更多