lienhua34
2014-11-24

1 取消线程

pthread 提供了pthread_cancel 函数用于请求取消同一进程中的其他线程。

#include <pthread.h>

int pthread_cancel(pthread_t tid);

返回值:若成功则返回0,否则返回错误编码

pthread_cancel 调用并不会立即终止目标线程,而只是向目标线程发出取消请求。调用线程不等待目标线程终止,在默认情况下,目标线程在取消请求发出以后还是继续运行的,直到目标线程到达某个取消点。取消点是线程检查是否被取消并按照请求进行动作的一个位置。

下面我们来看个线程取消的例子。主线程创建一个新线程,新线程循环睡眠 5 秒钟然后返回 2. 而主线程在创建新线程之后睡眠 2 秒钟便调用pthread_cancel 来请求取消新线程。最后获取新线程的退出状态。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h> void *
my_thread(void *arg)
{
int i=; printf("[new thread]: I will sleep 5 seconds.\n");
while (i < ) {
sleep();
i = i + ;
printf("[new thread]: %d\n", i);
}
printf("[new thread]: exit now.\n");
return ((void *));
} int
main(void)
{
int err;
pthread_t tid;
void *tret; err = pthread_create(&tid, NULL, my_thread, NULL);
if ( err != ) {
printf("can't create thread: %s\n", strerror(err));
exit(-);
} sleep();
printf("[main thread]: cancel new thread.\n");
err = pthread_cancel(tid);
if (err != ) {
printf("can't cancel thread: %s\n", strerror(err));
exit(-);
} err = pthread_join(tid, &tret);
if (err != ) {
printf("can't join with new thread: %s\n", strerror(err));
exit(-);
} else {
if (PTHREAD_CANCELED == tret) {
printf("new thread has been canceled.\n");
} else {
printf("new thread exit code: %d\n", (int)tret);
}
} exit();
}

编译该程序,生成并执行文件pthread_cancel_demo,

lienhua34:demo$ gcc -o pthread_cancel_demo -pthread pthread_cancel_demo.c
lienhua34:demo$ ./pthread_cancel_demo
[new thread]: I will sleep seconds.
[new thread]:
[main thread]: cancel new thread.
new thread has been canceled.

如果某个线程响应了取消请求相当于调用了参数为PTHREAD_CANCELED的pthread_exit 函数。

2 线程取消属性

前面学习了可以通过pthread_attr_t 结构来控制线程的属性。但是有两个与线程取消的属性没有包含在pthread_attr_t 结构中,它们是可取消状态和可取消类型。

2.1 可取消状态

可取消状态属性是个使能属性,控制了线程是否要响应其他线程的取消请求。该属性可以是PTHREAD_CANCEL_ENABLE,或者是PTHREAD_CANCEL_DISABLE。线程的可取消属性默认为前者。如果设置为后者,则线程将不会响应取消请求,不过取消请求对于该线程来说处于未决状态,当可取消状态再次变为PTHREAD_CANCEL_ENABLE 时,线程将在下个取消点上对所有未决的取消请求进行处理。

线程可以通过调用pthread_setcancelstate 函数来修改其可取消状态。

#include <pthread.h>

int pthread_setcancelstate(int state, int *oldstate);

返回值:若成功则返回0,否则返回错误编号

该函数将线程的当前可取消状态设置为 state,并通过 oldstate 返回原来的可取消状态。

下面我们来看那个例子,我们在上面的pthread_cancel_demo.c 程序的新线程入口函数my_thread 的开始调用pthread_setcancelstate 函数将新线程的可取消状态设置为PTHREAD_CANCEL_DISABLE。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h> void *
my_thread(void *arg)
{
int i=;
int err;
err = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (err != ) {
printf("[new thread]: can't set cancel state: %s\n", strerror(err));
}
printf("[new thread: disable cancel state.\n"); printf("[new thread]: I will sleep 5 seconds.\n");
while (i < ) {
sleep();
i = i + ;
printf("[new thread]: %d\n", i);
}
printf("[new thread]: exit now.\n");
return ((void *));
} int
main(void)
{
int err;
pthread_t tid;
void *tret; err = pthread_create(&tid, NULL, my_thread, NULL);
if ( err != ) {
printf("can't create thread: %s\n", strerror(err));
exit(-);
} sleep();
printf("[main thread]: cancel new thread.\n");
err = pthread_cancel(tid);
if (err != ) {
printf("can't cancel thread: %s\n", strerror(err));
exit(-);
} err = pthread_join(tid, &tret);
if (err != ) {
printf("can't join with new thread: %s\n", strerror(err));
exit(-);
} else {
if (PTHREAD_CANCELED == tret) {
printf("new thread has been canceled.\n");
} else {
printf("new thread exit code: %d\n", (int)tret);
}
} exit();
}

编译该程序,生成并执行pthread_cancel_demo 文件,

lienhua34:demo$ gcc -o pthread_cancel_demo -pthread pthread_cancel_demo.c
lienhua34:demo$ ./pthread_cancel_demo
[new thread: disable cancel state.
[new thread]: I will sleep seconds.
[new thread]:
[main thread]: cancel new thread.
[new thread]:
[new thread]:
[new thread]:
[new thread]:
[new thread]: exit now.
new thread exit code:

从上面的运行结果与前一节的运行结果对比,我们可以看出将新线程的可取消状态设置为PTHREAD_CANCEL_DISABLE 后,新线程没有响应主线程的取消请求。

2.2 可取消类型

上面所说的线程在到达某个取消点的时候会去检查一下是否被取消。这种取消类型也称为延迟取消。另外,还有一种取消类型是异步取消。当线程的取消类型为异步取消时,线程可以在任意时间被取消。

线程可以通过调用pthread_setcanceltype 来修改线程的取消类型。

#include <pthread.h>

int pthread_setcanceltype(int type, int *oldtype);

返回值:若成功则返回0,否则返回错误编号

其中type参数可以是PTHREAD_CANCEL_DEFERRED(延迟取消), 或者PTHREAD_CANCEL_ASYNCHRONOUS(异步取消)。该函数将线程的当前可取消类型设置为 type,然后将原来的可取消类型通过 oldtype 参数返回。

(done)

UNIX环境编程学习笔记(28)——多线程编程(三):线程的取消的更多相关文章

  1. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  2. Python Web学习笔记之多线程编程

    本次给大家介绍Python的多线程编程,标题如下: Python多线程简介 Python多线程之threading模块 Python多线程之Lock线程锁 Python多线程之Python的GIL锁 ...

  3. 网络编程学习笔记:Socket编程

    文的主要内容如下: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().connect ...

  4. linux网络编程学习笔记之五 -----并发机制与线程�

    进程线程分配方式 简述下常见的进程和线程分配方式:(好吧,我仅仅是举几个样例作为笔记...并发的水太深了,不敢妄谈...) 1.进程线程预分配 简言之,当I/O开销大于计算开销且并发量较大时,为了节省 ...

  5. python核心编程学习记录之多线程编程

  6. java网络编程学习笔记(四):线程池的实现

    package QQ; import java.util.LinkedList; /** * Created by hu on 2015/11/9. */ public class ThreadPoo ...

  7. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  8. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

  9. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  10. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

随机推荐

  1. C语言字符串格式化显示

    符号                  作用 ──────────────────────────     %d              十进制有符号整数     %i              输 ...

  2. ASP.NET学习笔记(3)——用户增删改查(三层)

    说明(2017-10-6 11:21:58): 1. 十一放假在家也没写几行代码,本来还想着利用假期把asp.net看完,结果天天喝酒睡觉,回去的票也没买到,惨.. 2. 断断续续的把用户信息的页面写 ...

  3. 1. CNN卷积网络-初识

    1. CNN卷积网络-初识 2. CNN卷积网络-前向传播算法 3. CNN卷积网络-反向更新 1. 前言 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面, 它的神经元间的连接是 ...

  4. CTF之PHP黑魔法总结

    继上一篇php各版本的姿势(不同版本的利用特性),文章总结了php版本差异,现在在来一篇本地日记总结的php黑魔法,是以前做CTF时遇到并记录的,很适合在做CTF代码审计的时候翻翻看看. 一.要求变量 ...

  5. visualstudio学习

    https://docs.microsoft.com/zh-CN/visualstudio/ide/get-started-with-visual-studio

  6. phpize的作用(资料整理)

    phpize的作用可以这样理解:侦测环境(phpize工具是在php安装目录下,基于这点phpize对应了当时的php环境,所以是要根据该php的配置情况生成对应的configure文件),建立一个c ...

  7. grep和rgrep和fgrep

    Linux环境下. (1)grep对标签元字符的表示. [berry@berry:practice] grep 'w\(es\).*\1' text northwest NW Charles Main ...

  8. JVM相关命题的博客整理及总结

    JVM垃圾回收基础介绍 http://www.jianshu.com/p/57457a351b8a 减少JVM中逃逸对象的使用 http://www.importnew.com/23150.html ...

  9. python多线程同步机制condition

    #!/usr/bin/env python# -*- coding: utf-8 -*- import threadingimport time def customer(cond): t = thr ...

  10. C#内置泛型委托:Action委托

    1.什么是Action泛型委托 Action<T>是.NET Framework内置的泛型委托,可以使用Action<T>委托以参数形式传递方法,而不用显示声明自定义的委托.封 ...