【问题标题】:thread_cancel and blocking function as cond_waitthread_cancel 和阻塞函数为 cond_wait
【发布时间】:2023-03-28 17:12:01
【问题描述】:

我让我的主进程将pthread_cancel 发送到另一个线程,该线程正在等待cond_wait(&condition) 发生条件。在pthread_cancel 他们说:延迟取消能力意味着取消将被延迟,直到线程下一次调用作为取消点的函数。但通常这些函数是阻塞函数。然后我的问题是线程仅在该线程被解除阻塞(在我的示例中通过广播或信号)后才取消,或者它会看到我当前在取消点阻塞然后取消我的线程?

【问题讨论】:

    标签: c++ pthreads mutex blocking


    【解决方案1】:

    我不熟悉cond_wait,但我认为它来自另一个库,而不是通常使用的pthread_cond_wait

    但是是的,如果一个线程在pthread_cond_wait 中被阻塞,然后被取消,该线程将被唤醒,重新获取它的互斥体,然后被取消。

    因此,当取消在某个条件下被阻塞的线程时,需要牢记两点:

    1. 在调用pthread_cancel 之前,确保互斥锁已解锁(或将在未来某个时间解锁)。例如,如果线程 A 正在等待某个条件,而线程 B 锁定了条件互斥锁,则在解锁条件互斥锁之前调用 pthread_cancelpthread_join,您将死锁。

    2. 在调用 pthread_cond_wait 之前安装清理处理程序(请参阅 pthread_cleanup_push)以解锁条件互斥锁 - 否则您将取消线程并使互斥锁保持锁定状态。

    但是,还要注意 pthread 条件变量实现已经/有一些错误 - 所以一定要使用最新的 glibc。

    【讨论】:

    • 为了确定,当线程退出 pthread_cond_wait 时,互斥锁重新锁定,但是如果互斥锁已经被锁定,它会等到互斥锁解锁吗?所以它等到互斥锁被释放才能取消线程?
    • 如果互斥锁已经被另一个线程锁定,那么执行pthread_cond_wait的线程将等到互斥锁被解锁,然后锁定互斥锁本身,然后被取消。
    【解决方案2】:

    您可能想要使用 pthread_cond_wait 而不是 cond_wait。

    如果你使用 pthread_cond_wait 并基于 man pthread_cond_wait(3)

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

    看起来线程将在 pthread_cond_wait 上取消,即使它当前被阻塞

    或者您可以使用 pthread_setcanceltype 将取消类型设置为 ASYNCHRONOUS。见下面的评论

    但与大多数时候一样,确定的最佳方法是使用测试代码进行尝试。

    【讨论】:

    • 永远不要使用异步取消,除了纯粹进行计算和类似的代码 - 也就是说,根本没有系统调用,除了 pthread_setcanceltype/statepthread_cancel,它们是唯一的异步-取消安全系统调用。即便如此,直接输入pthread_test_cancel 可能会更好。有关更多信息,请参阅此处的注释:linux.die.net/man/3/pthread_setcanceltype
    • 我正在使用延迟取消
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 2020-03-29
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    相关资源
    最近更新 更多