当前位置: 首页 > news >正文

Linux线程操作(创建,终止,等待,分离)

在使用Linux线程库时,需要包含头文件<pthread.h>,而且在链接时,需要包含-lphread选项。

创建线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(*start_routine)(void*), void *arg);

thread参数是输出型参数,会将thread指向的变量的值设置为线程ID,attr参数是设置线程的属性,为NULL表示使用默认属性,start_routine参数是一个函数指针,指向参数类型为void*,返回值类型为void*的一个函数,例如下面的函数

void* func(void* arg);

而最后一个参数arg会作为func函数的参数。

返回值为0表示成功,失败则返回错误码

pthreads函数在失败时不会像其他POSIX函数一样设置全局变量errno,而是返回错误码。

pthreads函数同样也提供了线程内的errno变量,以支持其他使用errno的代码。对于pthreads函数的错误,建议使用返回值判定,因为读取返回值的开销要更小。

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


void* thread_func(void* arg)
{
    return NULL;
}


int main()
{
    pthread_t thread;
    int err = pthread_create(&thread, NULL, thread_func, NULL);
    if(err)
    {
        fprintf(stderr, "pthread_create : %s\n", strerror(err));
        exit(EXIT_FAILURE);
    }
    pthread_join(thread, NULL);
    return 0;
}

现在可以创建线程为我们完成任务了。

获取线程ID

pthread_t pthread_self(void);

终止线程

只终止线程而不终止整个进程,可使用如下接口

void pthread_exit(void *value_ptr);

 value_ptr是线程退出时交给主线程的值,也就是线程的返回值,主线程可通过等待线程获得该值创建线程时会传入一个函数指针,这个函数指针指向的函数会返回一个void*类型的值,也就是线程的返回值。

注意返回的指针不要指向局部变量,因为返回时该局部变量已经被销毁了。

int pthread_cancel(pthread_t thread);

thread是线程ID,可以直接取消该线程。如果要使用,一般是主线程取消其他线程。在其他线程中取消主线程是未定义行为。

返回值为0表示成功,失败返回错误码。

需要注意在线程中使用exit函数时,会退出整个进程。

线程等待

int pthread_join(pthread_t thread, void **value_ptr);

 可以等待线程ID为thread的线程执行完任务,value_ptr指向线程的返回值,为NULL表示不关心返回值。

注意返回值有以下几种情况:

线程通过return返回,得到的返回值就是return的值

线程被调用pthread_cancel终止,value_ptr所指向的单元里存放常数PTHREAD_ CANCELED

线程调用pthread_exit终止,value指向的值是传给pthread_exit的参数

等待线程是为了回收这个线程的资源,避免造成类似僵尸进程的问题。

分离线程

默认情况下创建的线程是joinable的,线程退出后需要等待他以便回收资源。

如果不关心返回值,join是一种负担,这时,可以告诉系统,线程退出时,自动释放线程资源

int pthread_detach(pthread_t thread);

可以是线程组内其他线程对目标线程进行分离,也可以是线程分离自身

pthread_detach(pthread_self());

成功返回0,失败返回错误码

需要注意,线程不能既是joinable又是可分离的,也就是说,你不能等待一个被分离的线程

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

void* thread_func(void* arg)
{
    pthread_detach(pthread_self());
    return NULL;
}


int main()
{
    pthread_t thread;
    int err = pthread_create(&thread, NULL, thread_func, NULL);
    if(err)
    {
        fprintf(stderr, "pthread_create : %s\n", strerror(err));
        exit(EXIT_FAILURE);
    }
    //确保线程已经分离
    sleep(1);
    err = pthread_join(thread, NULL);
    if(err)
    {
        fprintf(stderr, "pthread_join : %s\n", strerror(err));
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("pthread_join success\n");
    }
    pthread_join(thread, NULL);
    return 0;
}

可用这段代码进行测试。

相关文章:

  • 基于STM32电子钟闹钟数码管显示设计(Proteus仿真+程序+设计报告+原理图PCB+讲解视频)
  • 二分查找的应用
  • numpy学习笔记3:三维数组 np.ones((2, 3, 4)) 的详细解释
  • 汽车相关液体介绍
  • MinIO Docker
  • Linux性能监控工具nmon安装及使用
  • 3.20-1ui自动化切换,登录退出
  • Object 转 JSONObject 并排除null和““字符串
  • 应急响应笔记
  • stm32 2.0.3.0
  • python-leetcode 60.分割回文串
  • K8S中若要挂载其他命名空间中的 Secret
  • h265 flv.js组件封装Vue3
  • 【软考-架构】8.4、信息化战略规划-CRO-SCM-应用集成-电子商务
  • 【Linux】VMware17 安装 Ubuntu24.04 虚拟机
  • Ubutu20.04安装docker与docker-compose
  • Spring Boot 异步返回对象深度解析
  • #pandas #python#数据标注 pd.crosstab()
  • STM32U575RIT6单片机(四)
  • 嵌入式c学习七
  • 因救心梗同学缺席职教高考的姜昭鹏顺利完成补考
  • 新时代,新方志:2025上海地方志论坛暨理论研讨会举办
  • 3月中国减持189亿美元美债、持仓规模降至第三,英国升至第二
  • 就规范涉企行政执法专项行动有关问题,司法部发布解答
  • “三个集中”之后:图说浦东新区28次撤乡并镇
  • A股午后拉升,沪指收复3400点:大金融发力,两市成交超1.3万亿元