【问题标题】:pthread_cancel when using mutexes an conditional variables使用互斥锁时的 pthread_cancel 条件变量
【发布时间】:2014-06-21 09:21:00
【问题描述】:

您好,我有一个关于取消使用互斥锁和条件变量的线程的问题。该线程具有延迟的取消类型。当我只使用函数pthread_mutex_lock/unlock 和pthread_cond_wait,并且取消请求到达时,线程的取消点只有pthread_cond_wait。它会锁定互斥锁吗?我不确定,如果线程总是让互斥锁解锁。还是 pthread_mutex_lock/unlock 函数也是取消点?谢谢。

【问题讨论】:

    标签: pthreads


    【解决方案1】:

    我怀疑我能比the documentation更好地表达这个:

    条件等待(无论是否定时)是一个取消点。什么时候 线程的可取消类型设置为 PTHREAD_CANCEL_DEFERRED, 在取消请求时采取行动的副作用 条件等待是之前(实际上)重新获取了互斥锁 调用第一个取消清理处理程序。效果就像 线程被解除阻塞,允许执行到 从调用 pthread_cond_timedwait() 或返回 pthread_cond_wait(),但此时注意到取消 请求而不是返回给调用者 pthread_cond_timedwait() 或 pthread_cond_wait(),启动线程 取消活动,包括调用取消清理 处理程序。

    还要确保您知道其他函数也是cancellation points

    【讨论】:

    • 打赌我是 15 秒 ...;-)
    • 是的,我相信我做到了^^
    • 好的,所以 pthread_cond_wait 在取消时可能会或可能不会锁定互斥锁。我最好禁用线程的可取消性,因为如果我的清理处理程序在没有拥有它的情况下解锁互斥锁,那将是一场灾难。是否有类似 sigpending 的功能来查看取消请求是否处于待处理状态?
    • 我不知道(this 可能相关)为什么不拥有自己的取消机制(可以简单且可预测的(take a look here))?
    • 如果您绝对必须使用cancel,您可以使用一个hacky 解决方案,首先将pthread_setcancelstate 禁用,然后在您准备好使用的位置启用它取消并在此之后立即致电pthread_testcancel(但这是一种黑客行为,我建议不要这样做:))。请考虑使用 V 符号 accepting the answer
    【解决方案2】:

    如果您有多个线程在pthread_cond_wait 上等待,并且在使用pthread_cond_broadcastpthread_cond_signal 发送某种广播之前调用pthread_cancel,那么它可能会导致pthread_cond_wait 正在等待的死锁on 线程要取消,线程正在等待 pthread_cond_wait 出来。

    【讨论】:

      【解决方案3】:

      根据“Linux 编程接口”一书的第 667-678 页 互斥锁将被锁定。所以你可以使用

      pthread_mutex_lock(&mutex);
      pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, &mutex);
      while (var == 0)) {
          pthread_cond_wait(&cond, &mutex);
      }
      pthread_cleanup_pop(1);
      

      【讨论】:

      • 可以这样做,但是由于pthread_mutex_unlock() 通过指向不兼容函数类型的指针被调用,您会在取消时获得未定义的行为。作为一个单独的问题,这是一个老问题,其答案仍然完全有效。欢迎您的贡献,但如果针对尚未有好的答案的问题,它们会更有帮助。
      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 2015-11-17
      • 2011-06-12
      相关资源
      最近更新 更多