前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POSIX之cancel

POSIX之cancel

作者头像
Taishan3721
发布2022-12-05 15:55:36
6680
发布2022-12-05 15:55:36
举报
文章被收录于专栏:这里只有VxWorks

线程在创建后,除了调用pthread_exit()主动退出,还可以被其它线程/任务通过pthread_cancel()来退出,这种机制叫做cancellation

代码语言:javascript
复制
/*
 * 向<thread>发送一个cancellation请求.
 * 根据线程的不同设置,
 * 线程可能忽略这个请求,
 * 或立即终止,
 * 或推迟到下一个cancellation point再终止.
 *
 * 线程终止时, 执行的操作类似于pthread_exit(), 不过返回值为'PTHREAD_CANCELED'.
 */
int pthread_cancel
    (
    pthread_t thread
    );

新创建的线程,默认就支持cancellation。其状态可以使用pthread_setcancelstate()来修改

代码语言:javascript
复制
/*
 * 将线程的cancellation状态设置为<state>,
 * 如果<oldstate>非NULL, 返回之前的状态.
 *
 * 状态值二选一:
 *   PTHREAD_CANCEL_ENABLE
 *   PTHREAD_CANCEL_DISABLE
 *
 * 新线程的默认状态为PTHREAD_CANCEL_ENABLE
 */
int pthread_setcancelstate
    (
    int state,
    int *oldstate
    );

这个cancellation类型有两种,通过pthread_setcanceltype()设置

代码语言:javascript
复制
/*
 * 将线程的cancellation类型设置为<type>,
 * 如果<oldtype>非NULL, 返回之前的类型.
 *
 * 类型值二选一:
 *   PTHREAD_CANCEL_ASYNCHRONOUS - 立即执行收到的cancellation请求
 *   PTHREAD_CANCEL_DEFERRED - 下一个cancellation point再执行cancellation
 *
 * 新线程的默认类型为PTHREAD_CANCEL_DEFERRED
 */
int pthread_setcanceltype
    (
    int type,
    int *oldtype
    );

如何添加cancellation point呢?可以使用pthread_testcancel()

代码语言:javascript
复制
/*
 * 为当前线程创建一个cancellation point.
 *
 * 如果已经enable cancellation,
 * 并且cancellation类型是PTHREAD_CANCEL_DEFERRED,
 * 并且已经收到cancellation请求,
 * 则调用pthread_exit()并返回'PTHREAD_CANCELED'.
 */
void pthread_testcancel();

那为什么第一个例子里的sleep()也可以cancel呢?是因为OS的一些API使用了一个pthread_testandset_canceltype()

代码语言:javascript
复制
/*
 * 相当于先执行pthread_testcancel(), 再执行pthread_setcanceltype().
 */
int pthread_testandset_canceltype
    (
    int type,
    int *oldtype
    );

都有哪些呢

函数

aioPxLib

aio_suspend()

ioLib

creat(), open(), read(), write(), close(), fsync(), fdatasync()

mqPxLib

mq_receive(), mq_send()

pthreadLib

pthread_cond_timedwait(), pthread_cond_wait(), pthread_join(), pthread_testcancel()

semPxLib

sem_wait()

sigLib

pause(), sigsuspend(), sigtimedwait(), sigwait(), sigwaitinfo()

timerLib

sleep(), nanosleep()

cancellation这种行为,线程本身很难预测,因此线程使用的一些系统资源就无法按照正常退出的流程去释放。这种情况,可以使用pthread_cleanup_push()来注册一些清理函数。而在正常退出之前,可以使用pthread_cleanup_pop()将其取消

代码语言:javascript
复制
/*
 * 添加cancellation清理函数<routine>.
 * 线程退出时, 按照添加顺序的倒叙、使用参数<arg>执行.
 */
void pthread_cleanup_push
    (
    void (*routine)(void *),
    void *arg 
    );
/*
 * 删除最后添加的清理函数.
 * 如果<run>非0, 则执行它.
 */
void pthread_cleanup_pop
    (
    int run
    );
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 这里只有VxWorks 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档