如何使用pthread_mutex_destroy安全地销毁互斥锁

时间:2014-04-11 20:17:20

标签: c++ multithreading synchronization pthreads mutex

我有一个包含一些逻辑并且有一个工作线程的类,有几个函数可以检查到目前为止完成的工作的状态。 我使用互斥量包装对内部数据和检查的更改,api要求有一个信号函数告诉类开始关闭,这意味着没有新的请求可以处理,但只要旧的仍然是在进展中,可以检查他们的状态。

我的问题是我很难决定何时安全销毁互斥锁​​,因为我解锁它的那一刻,可能会有另一个线程试图检查某个工作的状态,我最终会毁掉一个锁定的互斥锁是坏的。 有什么建议?

  • 编辑:这可行吗? ATOMIC_BLOCK(ATOMIC_RESTORESTATE)  {    调用pthread_mutex_unlock(安培; OM);    pthread_mutex_destroy(安培; OM);  } (使用asm / atomic.h中的宏)*

不应该像看起来那样使用......

EDIT2:

假设我有以下功能:

void queue_image(image pic){
     pthread_mutex_lock(&mo);
     // add 
     pthread_mutex_unlock(&mo);
}

void is_pic_processed(string pic_id){
    pthread_mutex_lock(&mo);
     // chech whether pic was processed
     pthread_mutex_unlock(&mo);
}

void * process(void* arg){ //this is in another thread
    while(1){
      pthread_mutex_lock(&mo);
      if(kill_flag && no more work){ 
         pthread_mutex_unlock(&mo);
(1)      /* the problem is here because in the meanwhile 
            someone could've called is_pic_processed locked the mutex 
            and now I'm destroying a locked mutex which is undesirable */
         pthread_mutex_destroy(&mo);
      }
      // do more work 
      pthread_mutex_unlock(&mo);
    }
}

void kill(){ // has to return and not wait for the remaining processing to take place
     pthread_mutex_lock(&mo);
     // set flag to end the work 
     pthread_mutex_unlock(&mo);
}

kill只是停止处理,而不是整个应用程序,我在没有问题的其他线程调用is_pic_processed 销毁互斥锁​​并获得适当的错误后我遇到了问题在尝试首先销毁互斥锁​​时调用,希望这会稍微解决一下这个问题。

1 个答案:

答案 0 :(得分:0)

我不明白这个问题。只要还有"正在进行"你就不应该销毁互斥锁​​。请求。

工作线程本身应检查请求队列以及" shutdown"函数被称为它应该破坏互斥体,并且可能会死掉。

所以:

  • 没有人会尝试锁定互斥锁,因为所有请求都已处理且没有正在进行的请求
  • 一旦锁定的互斥锁被锁定并将其销毁,就可以安全地销毁锁定的互斥锁

希望我正确理解这个问题:)

编辑2后

您添加的内容与您之前说过的内容存在冲突:

  

只要旧的仍处于进展状态,就可以检查其状态。

您现在正在说,即使他们不再进行“进展”,也可以检查他们的状态。

无论如何这不是问题。因为您可以在{。1}} 之前拨打pthread_mutex_destroy来呼叫pthread_mutex_unlock

我将其用作来源The Open Group Base Specifications Issue 7 - pthread.h

编辑3 : 我想在我的回答中添加一些东西:你需要在这里进行一些重新设计。

即使您可以在锁定时销毁该互斥锁,也需要确保没有其他线程可以在它被销毁后尝试锁定它,例如通过检查您现在完成的请求的状态。

换句话说,如果你想销毁互斥锁​​,那么在" kill flag"之后就不可能使用互斥锁来检查请求的状态。已经确定。