SylixOS中pthread_cancel函数浅析

1 知识简介

1.1 概述

取消一个线程要确保该线程能够释放其所持有的任何锁、分配的内存,使整个系统保持一致性。在很多复杂情况下要保证这种正确性是有一定困难的。

一种简单的线程取消:取消线程调用一个取消线程的函数,被取消线程死亡。在这种情况下,被取消线程所持有的的资源得不到释放。取消线程负责保证被取消者处于可安全取消状态,在一个要求可靠性高的系统中,这种保证非常困难或者无法实现。这种取消称为不受限制的异步取消

还存在另外一种更安全的线程取消机制。一个线程可以以可靠的受控制的方式向进程的其他线程发出取消请求,目标线程可以挂起这一请求使实际的取消动作在此后安全的时候进行,称为延迟取消。目标线程还可以定义其被取消后自动被系统调用的线程清除函数。

SylixOS兼容绝大多数POSIX接口, SylixOSpthread_cancel函数执行线程取消功能。

pthread_cancel 函数和目标线程的取消动作是异步的。根据目标线程的取消属性不同,取消请求可能被忽略、立即执行或者延迟处理。为了清楚这些动作,下面知识点先简单介绍线程取消属性相关概念。

1.2 知识点

SylixOSpthread_cancel函数由px_pthread.h头文件定义,其原型为:

int  pthread_cancel (pthread_tthread);

  •   此函数成功返回 0,失败返回错误号;

  •  参数 thread 是取消的线程句柄。

 

SylixOS中用取消状态,取消类型和取消请求这3个元素共同表示一个线程的取消属性,其存在于线程控制块中。如表2-1所示。

  2-1  取消说明

wKioL1ikSfXRxVIxAACmZmogJuc228.png

线程初始化时会有默认的取消属性,即线程保留允许取消延迟取消的属性,保证收到取消信号时,线程接受该取消信号,不会屏蔽掉,并且会在自身安全的时候,调用线程删除函数,即延迟取消。另外一个线程的取消状态和取消类型可分别调用相关函数设置,如表 2-2所示。函数均在px_pthread.h头文件中定义。

2-2  设置取消属性

wKiom1ikRw2yo4fEAAA3ugNAcKA024.png

前文提到,延迟请求会使线程的取消动作在安全的时候进行,那线程具体的取消时机是在什么时候呢?会涉及到“取消点”的概念,在后续章节中介绍。

2 技术实现

2.1 实现流程

SylixOSpthread_cancel函数实现机制,如图3-1所示

 wKioL1iYAmHAVLmNAAEAA3x3-lA865.png

3-1  pthread_cancel函数实现流程

2.2 “取消点”概念

在使用延迟取消机制时,一个线程在可以被取消的地方定义取消点,当收到取消请求时,被取消的线程执行到取消点时退出,或者在一个取消点调用被阻塞时退出。

由于在延迟取消中必须在取消点才能被取消,这一限制可能使取消请求被挂起任意长时间。因此,如果某个调用可能使线程被阻塞或者进入某个较长时间的过程, POSIX 要求这些调用属于一个取消点,或者称这些调用为取消点调用,以防止取消请求陷入长时间等待,SylixOS中存在一些拥有取消点的函数,如openreadpthread_joinprintf等,他们都直接或间接的调用了pthread_testcancel函数pthread_testcancel函数内部实现流程如图 3-2所示。

wKiom1iYAn2hsKUjAABA5woCxI0456.png

3-2  pthread_testcancel函数实现流程

因此,被取消线程会在执行拥有取消点的函数时,进入到pthread_testcancel函数内部,进行如图 32所示的允许取消、延迟取消以及取消请求标志的判断流程,倘若条件满足,被取消线程会在这里调用线程删除函数删除自身。

3-1列出部分拥有取消点的函数以供参考。

3-1  拥有取消点的函数

wKioL1ikR22gCgeXAAA8WRbqnBI554.png

3 示例演示

以下示例验证均在SylixOS环境下进行。

3.1 示例1:立即取消

如图 4-1所示,子线程设置立即取消类型,那么主线程成功发送取消信号后,打印"pthread_cancel OK",子线程会在下次执行开始处删除自身,退出时子线程i的值可能为0~1000000任意值。

wKioL1iYArTw47buAABMBXFN5cU694.png

4-1  立即取消示例

3.2 示例2:延迟取消

如图 4-2所示,子线程设置延迟取消类型,那么主线程执行取消线程函数后,打印“pthread_cancel OK”,子线程会在执行到取消点时删除自身,sleep为拥有取消点的函数,因此子线程退出时i 的值一定为1000000。(pthread_cancel函数成功返回并不能代表目标线程已经退出

wKiom1iYDZ6j-_M_AABXu4tA1Kg449.png

4-2  延迟取消示例

倘若示例1和示例2都把子线程中入口函数中的sleep(1)这条语句去掉,那么示例1中的立即取消仍然有效;示例2中的延迟取消虽然主线程打印“pthread_cancel OK”,但是因为子线程的while(1)循环里没有“取消点”,子线程的取消请求一直都不能被处理,因此子线程并不会被成功取消,而是继续循环运行。如图 4-3所示。

wKiom1iYAt6y0X_nAABVLO596B4108.png

4-3 没有“取消点”

不过我们可以手动加入pthread_testcancel函数进行取消请求处理,这样子线程也就有了一个“取消点”,在“取消点”取消请求被处理,线程即可退出。如图 4-4所示。

wKiom1iYAvHjXY7HAABhNHfxpO4272.png

4-4  pthread_testcancel处理取消请求

4 总结

立即取消会通过信号方式修改目标线程任务上下文环境,即把旧目标线程任务上下文做

适当偏移,将信号处理句柄安装在上下文开始处,组成新的目标线程任务上下文,当任务调度轮到目标线程执行时,目标线程会优先执行信号处理程序,完成信号请求的动作。这里要注意时任务调度之后立即取消,因为任务调度切换任务上下文会花费一些时间,所以立即取消并不代表时间上的“立刻”。

延迟取消仅仅使目标线程的线程控制块相关标志修改,在目标线程执行到相关拥有取消点的函数时,进行取消请求检查,满足条件才会删除线程。即任务调度之后,目标线程还会继续执行任务上下文指定任务,直到碰到“取消点”,才可能取消线程。

pthread_cancel的成功返回仅仅表明调用该函数的线程完成了对目标线程线程控制块相关标志的修改,等到任务调度,目标线程才会检查这些标志,做出相应处理,即pthread_cancel的成功返回并不能代表目标线程的完全取消。

由此可见,线程取消并不是安全的,立即取消会让目标线程“立即退出”,延迟取消会给目标线程从开始到“取消点”争取一段执行时间,如果没有“取消点”,目标线程就不能完成预期的线程取消动作,这些都有可能造成很多不安全的因素,目标线程取消之前占有的资源如互斥锁,互斥锁没有释放线程就退出了,将导致别的线程无法获得改锁从而一直阻塞,更严重的还会造成死锁现象。

线程退出时可以调用线程清理处理程序,通过pthread_cleanup_pop和pthread_cleanup_push函数可以将有些“后事”在线程退出后交给线程清理处理程序帮忙处理,本文档此次主要浅析SylixOSpthread_cancel流程,就不对线程清理处理程序如何使用做详细介绍了。


5 参考资料

SylixOS内核源码

 《SylixOS应用程序开发手册》

 

优秀的个人博客,低调大师

微信关注我们

原文链接:https://blog.51cto.com/gedongrui/1895231

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。