7、取消点的进一步讨论(转)

本文详细介绍了POSIX标准下的线程取消机制,包括线程取消点的概念、与线程取消相关的pthread函数及其使用方法,并通过示例代码展示了线程取消的具体实现过程。

7、取消点的进一步讨论

 

线程取消的方法是向目标线程发Cancel信号,但如何处理Cancel信号则由目标线程自己决定,或者忽略、或者立即终止、或者继续运行至Cancelation-point(取消点),由不同的Cancelation状态决定。

线程接收到CANCEL信号的缺省处理(即pthread_create()创建线程的缺省状态)是继续运行至取消点,也就是说设置一个CANCELED状态,线程继续运行,只有运行至Cancelation-point的时候才会退出

(1)什么是线程取消点

根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()等会引起阻塞的系统调用都是Cancelation-point,而其他pthread函数都不会引起Cancelation动作。但是pthread_cancel的手册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是Cancelation-point;但CANCEL信号会使线程从阻塞的系统调用中退出,并置EINTR错误码,因此可以在需要作为Cancelation-point的系统调用前后调用pthread_testcancel(),从而达到POSIX标准所要求的目标,即如下代码段:

pthread_testcancel();

retcode = read(fd, buffer, length);

(2)与线程取消相关的pthread函数

int pthread_cancel(pthread_t thread)

发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。

int pthread_setcancelstate(int state,   int *oldstate)  

设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。  

int pthread_setcanceltype(int type, int *oldtype)  

设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。  

void pthread_testcancel(void)

Calling pthread_testcancel() creates a cancellation point within the calling thread, so that a thread that is otherwise executing code that contains no cancellation points will respond to a cancellation request.

If cancelability is disabled (using pthread_setcancelstate(3)), or no cancellation request is pending, then a call to pthread_cancel(3) has no effect.

也就是说pthread_testcancel在不包含取消点,但是又需要取消点的地方创建一个取消点,以便在一个没有包含取消点的执行代码线程中响应取消请求。

示例代码【3】

View Code
复制代码
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

staticint done =0;
staticint cleanup_pop_arg =0;
staticint cnt =0;

staticvoid
cleanup_handler(void*arg)
{
printf("Called clean-up handler\n");
cnt =0;
}

staticvoid*
thread_start(void*arg)
{
time_t start, curr;
printf("New thread started\n");
pthread_cleanup_push(cleanup_handler, NULL);
curr = start = time(NULL);

while (!done) {
pthread_testcancel(); /* A cancellation point */
if (curr < time(NULL))
{
curr = time(NULL);
printf("cnt = %d\n", cnt); /* A cancellation point */
cnt++;
}
}

pthread_cleanup_pop(cleanup_pop_arg);
return NULL;
}

int
main(int argc, char*argv[])
{
pthread_t thr;
int s;
void*res;

s = pthread_create(&thr, NULL, thread_start, NULL);
if (s !=0)
handle_error_en(s, "pthread_create");

sleep(2); /* Allow new thread to run a while */

if (argc >1)
{
if (argc >2)
cleanup_pop_arg = atoi(argv[2]);
done =1;

}
else
{
printf("Canceling thread\n");
s = pthread_cancel(thr);
if (s !=0)
handle_error_en(s, "pthread_cancel");
}

s = pthread_join(thr, &res);
if (s !=0)
handle_error_en(s, "pthread_join");

if (res == PTHREAD_CANCELED)
printf("Thread was canceled; cnt = %d\n", cnt);
else
printf("Thread terminated normally; cnt = %d\n", cnt);
exit(EXIT_SUCCESS);
}
复制代码

 

 

 

示例代码跟踪

View Code
复制代码
[root@localhost CFunctionTest]# ./thread
New thread started
cnt =0
cnt =1
Canceling thread
Called clean-up handler
Thread was canceled; cnt =0
[root@localhost CFunctionTest]# gdb thread
(gdb) b 18
//...
(gdb) r
Starting program: /home/***/a***/CFunctionTest/thread
[Thread debugging using libthread_db enabled]

Breakpoint 6, main (argc=1, argv=0xbffff374) at testthread.cpp:54
54 s = pthread_create(&thr, NULL, thread_start, NULL);
Missing separate debuginfos, use: debuginfo-install glibc-2.12.90-17.i686 libgcc-4.5.1-4.fc14.i686 libstdc++-4.5.1-4.fc14.i686
(gdb) n
[New Thread 0xb7fecb70 (LWP 4845)]
New thread started
[Switching to Thread 0xb7fecb70 (LWP 4845)]

Breakpoint 2, thread_start (arg=0x0) at testthread.cpp:29
29 pthread_cleanup_push(cleanup_handler, NULL);
(gdb) n
31 curr = start = time(NULL);
(gdb) n
33while (!done) {
(gdb) n

Breakpoint 3, thread_start (arg=0x0) at testthread.cpp:34
34 pthread_testcancel(); /* A cancellation point */
(gdb) n
Canceling thread
[Switching to Thread 0xb7fee6d0 (LWP 4840)]

Breakpoint 7, main (argc=1, argv=0xbffff374) at testthread.cpp:70
70 s = pthread_cancel(thr);
(gdb) n
cnt =0
[Switching to Thread 0xb7fecb70 (LWP 4845)]

Breakpoint 4, thread_start (arg=0x0) at testthread.cpp:39
39 cnt++;
(gdb) n
33while (!done) {
(gdb) n

Breakpoint 3, thread_start (arg=0x0) at testthread.cpp:34
34 pthread_testcancel(); /* A cancellation point */
(gdb) n
35if (curr < time(NULL))
(gdb) n
37 curr = time(NULL);
(gdb) n
38 printf("cnt = %d\n", cnt); /* A cancellation point */
(gdb) n
cnt =1
[Switching to Thread 0xb7fee6d0 (LWP 4840)]

Breakpoint 8, main (argc=1, argv=0xbffff374) at testthread.cpp:75
75 s = pthread_join(thr, &res);
(gdb) n
[Switching to Thread 0xb7fecb70 (LWP 4845)]

Breakpoint 4, thread_start (arg=0x0) at testthread.cpp:39
39 cnt++;
(gdb) n
33while (!done) {
(gdb) n

Breakpoint 3, thread_start (arg=0x0) at testthread.cpp:34
34 pthread_testcancel(); /* A cancellation point */
(gdb) n

Breakpoint 1, cleanup_handler (arg=0x0) at testthread.cpp:18
18 printf("Called clean-up handler\n");
(gdb) n
Called clean-up handler
19 cnt =0;
(gdb) n
20 }
(gdb) n
复制代码

 

 

 

参考:

【1】 http://blog.youkuaiyun.com/yanook/article/details/6589798

【2】 http://blog.youkuaiyun.com/yulanarti/article/details/6197769

【3】 http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cleanup_push.3.html

转载于:https://www.cnblogs.com/qq78292959/archive/2013/01/17/2864389.html

weboffice 7.0版本信息与下载 更新时间: 2013年 9月 4日 12:16 星期三 1. 产品说明 WEBOFFIC是北京聚信息技术有限公司开发的一款文档编辑组件,其主要用户打开各种格式的文档。 目前支持的主流文件格式有:Word、Excel、WPS等编辑文档。 WEBOFFICE是标准的ACTIVEX组件,支持在应用开发平台中嵌入整合。 C/S平台:VB、VC、Delphi … … B/S平台:ASP、PHP、Java、ASP.Net、C#.Net … … 功能项 详细说明 文件格式 支持大多数的文件格式,如Word、Excel、WPS… …。 修订留痕 Word中实现修订留痕功能,鼠标置于留痕之上,显示修订信息。 安全设置 接口调用限制打印、保存、复制。 文件上传 直接保存到服务器,支持标准的HTTP Post协议。 书签管理 通过书签管理实现表单数据与Word书签交互。 公文套红 支持公文套红功能。 区域保护 支持在Word中分区域保护Word指定的数据。 与weboffice6相对,修改了文档打开模式,通过OLE方式调用Office软件,处理机制类似微软DSOFramer组件,相对weboffice6完全打开模式,打开文档速度大大提升。 同时weboffice7推出了标准版和增强版; 免费版用于服务免费用户群体,满足office最基本的在线编辑,保存,打开,修订,保护,套红等常用功能,随时根据新的环境系统免费升级。 增强版用于特殊订制开发用户,提供了office区域控制实现了在office中控制特殊区域选择定好的内容或者控制指定区域编辑权限;也提供了pdf的生成功能;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值