Linux线程处理—线程终止

23 篇文章 0 订阅
10 篇文章 0 订阅

线程处理—线程终止

1.相关函数

线程终止有以下几种方法:

  1. 线程函数执行 return 语句;
  2. 线程函数内部调用 pthread_exit 函数;
  3. 其他线程调用 pthread_cancel 函数。

1.1系统调用pthread_exit

线程终止函数为 pthread_exit:

#include <pthread.h>
/**
* 结束关闭调用该方法的线程,并返回一个内存指针用于存放结果
* void *retval: 要返回给其它线程的数据
*/
void pthread_exit(void *retval);

当某个线程调用 pthread_exit 方法后,该线程会被关闭(相当于 return)。线程 可以通过 retval 向其它线程传递信息,retval 指向的区域不可以放在线程函数的栈内。 其他线程(例如主线程)如果需要获得这个返回值,需要调用 pthread_join 方法。

1.2系统调用pthread_join

#include <pthread.h>
/**
 * 等待指定线程结束,获取目标线程的返回值,并在目标线程结束后回收它的资源
* 
* pthread_t thread: 指定线程 ID
* void **retval: 这是一个可选参数,用于接收线程结束后传递的返回值。如果非空,
pthread_join 会在成功时将线程的 exit status 复制到 *retval 所指向的内存位置。
如果线程没有显式地通过 pthread_exit 提供返回值,则该参数将被设为 NULL 或忽略
* return: int 成功 0
* 失败 1
*/
int pthread_join(pthread_t thread, void **retval);

1.3系统调用pthread_detach

#include <pthread.h>
/**
* @brief 将线程标记为 detached 状态。POSIX 线程终止后,如果没有调用
pthread_detach 或 pthread_join,其资源会继续占用内存,类似于僵尸进程的未回收
状态。默认情况下创建线程后,它处于可 join 状态,此时可以调用 pthread_join 等待
线程终止并回收资源。但是如果主线程不需要等待线程终止,可以将其标记为 detached
状态,这意味着线程终止后,其资源会自动被系统回收。
* 
* @param thread 线程 ID
* @return int 成功返回 0,失败返回错误码
*/
int pthread_detach(pthread_t thread);

1.4系统调用pthread_cancel

#include <pthread.h>
/**
* @brief 向目标线程发送取消请求。目标线程是否和何时响应取决于它的取消状态和类
型
* 取消状态(Cancelability State):可以是 enabled(默认)或 disabled。如果
取消状态为禁用,则取消请求会被挂起,直至线程启用取消功能。如果取消状态为启用,
则线程的取消类型决定它何时取消。
* 取消类型(Cancelability Type):可以是 asynchronous(异步)或 deferred
(被推迟,默认值)。
* asynchronous:意味着线程可能在任何时候被取消(通常立即被取消,但系统
并不保证这一点)
* deferred:被推迟意味着取消请求会被挂起,直至被取消的线程执行取消点
(cancellation point)函数时才会真正执行线程的取消操作。
* 取消点函数:是在 POSIX 线程库中专门设计用于检查和处理取消请求的函数。
当被取消的线程执行这些函数时,如果线程的取消状态是 enabled 且类型是 deferred,
则它会立即响应取消请求并终止执行。man 7 pthreads 可以看到取消点函数列表。
* 
* @param thread 目标线程,即被取消的线程
* @return int 成功返回 0,失败返回非零的错误码
* 需要注意的是,取消操作和 pthread_cancel 函数的调用是异步的,这个函数
的返回值只能告诉调用者取消请求是否成功发送。当线程被成功取消后,通过
pthread_join 和线程关联将会获得 PTHREAD_CANCELED 作为返回信息,这是判断取消是
否完成的唯一方式
*/
int pthread_cancel(pthread_t thread);

1.5系统调用pthread_setcancelstate

#include <pthread.h>
/**
* @brief 设置调用线程的取消状态
* PTHREAD_CANCEL_ENABLE:启用取消功能
* PTHREAD_CANCEL_DISABLE:禁用取消功能
* 
* @param state 目标状态
* @param oldstate 指针,用于返回历史状态
* @return int 成功返回 0,失败返回非零错误码
*/
int pthread_setcancelstate(int state, int *oldstate);
6)pthread_setcanceltype
#include <pthread.h>
/**
* @brief 设置调用线程的取消类型
* PTHREAD_CANCEL_DEFERRED:设置取消类型为推迟
* PTHREAD_CANCEL_ASYNCHRONOUS:设置取消类型为异步
* 
* @param type 目标类型
* @param oldtype 指针,用于接收历史类型
* @return int 成功返回 0,失败返回非零错误码
*/
int pthread_setcanceltype(int type, int *oldtype);

2.实例

2.1pthread_join 测试例程

//
// Created by root on 2024/9/17.
//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>

//定义结构体接收线程结果
typedef struct {
    char *ptr;
    int len;
} Result;

//线程tid_red的函数

void *thread_red(void *argv) {
    //初始化Result结构体
    Result *result1 = (Result *) malloc(sizeof(Result));
    //获取线程参数
    char *code = (char *) argv;
    //创建缓冲区
    char *buffer = (char *) malloc(sizeof(char) * 101);
    while (1) {
        fgets(buffer, 100, stdin);
        if (buffer[0] == code[0]) {
            free(buffer);
            printf("Red thread exit\n");
            char *res = strdup("Red她离开了\n");
            result1->ptr = res;
            result1->len = strlen(res);
            //结束线程,返回结果
            pthread_exit((void *) result1);
        } else {
            printf("Red thread continue\n");
        }
    }
}

//线程tid_white的函数
void *thread_white(void *argv) {
    //初始化Result结构体
    Result *result2 = (Result *) malloc(sizeof(Result));
    //获取线程参数
    char *code = (char *) argv;
    //创建缓冲区
    char *buffer = (char *) malloc(sizeof(char) * 101);
    while (1) {
        fgets(buffer, 100, stdin);
        if (buffer[0] == code[0]) {
            free(buffer);
            printf("White thread exit\n");
            char *res = strdup("White她离开了\n");
            result2->ptr = res;
            result2->len = strlen(res);
            //结束线程,返回结果
            pthread_exit((void *) result2);
        } else {
            printf("White thread continue\n");
        }
    }
}


int main(int argc, char *argv[]) {
    //创建两个线程
    pthread_t tid_red;
    pthread_t tid_white;
    char red_code = 'r';
    char white_code = 'w';
    Result *result_red=NULL;
    Result *result_white=NULL;

    //创建线程red
    pthread_create(&tid_red, NULL, thread_red, &red_code);
    //创建线程white
    pthread_create(&tid_white, NULL, thread_white, &white_code);

    //获取线程red的返回值
    pthread_join(tid_red,(void **)&result_red);
    printf("Red的结局%d是:%s\n",result_red->len,result_red->ptr);
    //释放内存
    free(result_red);
    //获取线程white的返回值
    pthread_join(tid_white,(void **)&result_white);
    printf("White的结局%d是:%s\n",result_white->len,result_white->ptr);
    //释放内存
    free(result_white);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值