← 返回首页
Linux高级程序设计(七十四)
发表时间:2021-12-24 20:47:07
线程的取消

1.pthread_cancel

pthread_cancel函数可以杀死(取消)线程,其作用,对应进程中kill()函数。pthread_cancel的本质是发送信号给要取消的线程,使目标线程结束。

注意:信号发送成功并不意味着目标thread会终止。

#include <pthread.h>
int pthread_cancel(pthread_t thread);

参数: - thread:要杀死线程的tid。

返回值: - 成功返回0,失败返回错误号。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thr_fn(void *arg)
{

    printf("son thread is running...\n");
    int i=0;
    while(1)
    {
        printf("i=%d\n", i);
        i++;
        sleep(1);
    }
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    if (pthread_create(&thread, NULL, thr_fn, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    sleep(5);
    //5秒钟之后子线程退出   
    pthread_cancel(thread);
    if (pthread_join(thread, NULL) != 0)
    {
        perror("error to join:");
        exit(-1);
    }

    printf("main thread will exit....\n");
    return 0;
}

执行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
son thread is running...
i=0
i=1
i=2
i=3
i=4
main thread will exit....

2.设置线程的取消状态 线程的取消状态有以下两种: - PTHREAD_CANCEL_ENABLE(缺省) - PTHREAD_CANCEL_DISABLE

#include <pthread.h>
int pthread_setcancelstate(int state,   int *oldstate);

参数: - state: 取消状态 - oldstate: old_state如果不为NULL则存入原来的Cancel状态以便恢复。

返回值: - 成功返回0,失败返回非0

实例:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thr_fn(void *arg)
{
    //设置线程不可取消
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);

    printf("son thread is running...\n");
    int i=0;
    while(1)
    {
        printf("i=%d\n", i);
        i++;
        sleep(1);
    }
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    if (pthread_create(&thread, NULL, thr_fn, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }

    sleep(5);
    //5秒钟之后子线程退出   
    pthread_cancel(thread);
    if (pthread_join(thread, NULL) != 0)
    {
        perror("error to join:");
        exit(-1);
    }

    printf("main thread will exit....\n");
    return 0;
}

运行结果: 发现子线程无法取消。

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
son thread is running...
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
...

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

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

pthreads标准指定了几个取消点,其中包括: 1. 通过pthread_testcancel调用以编程方式建立线程取消点。 2. 线程等待pthread_cond_wait或pthread_cond_timewait()中的特定条件。 3. 被sigwait(2)阻塞的函数 4. 一些标准的库调用。通常,这些调用包括线程可基于阻塞的函数。

缺省情况下,将启用取消功能。有时,您可能希望应用程序禁用取消功能。如果禁用取消功能,则会导致延迟所有的取消请求,直到再次启用取消请求。 根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()等会引起阻塞的系统调用都是Cancelation-point。

pthread_testcancel函数用来设置线程的取消点

#include <pthread.h>
void pthread_testcancel(void)

4.设置线程的取消类型

线程的取消类型有以下两种: - PTHREAD_CANCEL_ASYCHRONOUS 立即取消 - PTHREAD_CANCEL_DEFFERED 不立即取消

pthread_setcanceltype函数用来设置线程的取消类型。

#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype)