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. 【Android】按钮点击事件的常用写法

    学习总结: 最近学习了Android点击事件的常用写法.点击事件会触发监听对象身上的回调,常用写法有以下四种: 方法一:使用匿名内部类. public class MainActivity exten ...

  2. 【React全家桶入门之十】登录与身份认证

    细致想想,我们的后台系统还没有一个登录功能,太不靠谱,赶紧把防盗门安上! SPA的鉴权方式和传统的web应用不同:因为页面的渲染不再依赖服务端,与服务端的交互都通过接口来完毕,而REASTful风格的 ...

  3. 云服务器启动tomcat巨慢,很慢

    增加随机数生成熵池 0.查看熵池 cat /proc/sys/kernel/random/entropy_avail 1. yum install rng-tools 2. systemctl sta ...

  4. css3常用动画样式文件move.css

    move.css zoomIn  zoomInDownouter-circlearrowTop expandOpen fadeIn  fadeInNormal  fadeInUp   fadeInRi ...

  5. php 扫描 下载 apk

    $file = 'C:\WebSiteDirectory\CarparkWeixinBackend\Dplus.apk'; if (file_exists($file)) { header('Cont ...

  6. Sublime Text 3 For Mac

    安装 Sublime Text 3 下载地址:http://www.sublimetext.com/3 我此时使用的是Build 3083版本. 安装 Package Control 这个是精华所在, ...

  7. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  8. JAVA中如何用接口实现多继承和多态 (非常好)

    ---------------------------------------------------------------多态1.JAVA里没有多继承,一个类之能有一个父类.而继承的表现就是多态. ...

  9. (转)st(state-threads) coroutine调度

    目录(?)[-] EPOLL和TIMEOUT TIME TIMEOUT Deviation   st(state-threads) https://github.com/winlinvip/state ...

  10. (转)live555学习笔记9-h264 RTP传输详解(1)

    九 h264 RTP传输详解(1) 前几章对Server端的介绍中有个比较重要的问题没有仔细探究:如何打开文件并获得其SDP信息.我们就从这里入手吧. 当RTSPServer收到对某个媒体的DESCR ...