Linux线程总结---线程的创建、退出、取消、回收、分离属性

简介: Linux线程总结---线程的创建、退出、取消、回收、分离属性

一、线程的基本概念

  1、基本概念
  线程是特殊的进程,在操作系统中,线程不能独立存在,线程是进程创建出来的,一个进程可以有多个线程,进程退出了,线程也会跟着退出。
  2、资源
  每个进程都有自己独立的堆、栈、数据段、代码段等空间,线程基本没有独立的资源,只有必不可少的资源(栈),同一进程之间的线程共享进程中的所有资源。


二、线程相关的API

1、线程创建函数

thread:存放线程的id

attr:线程的分离属性—>NULL

start_routine :参数为void *, 返回值也是void * 类型的函数指针。(线程执行函数)

arg:函数的参数

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

代码段:

void * Pthread_Task(void *arg)// arg = data;
{
  int a = (long)arg;
  printf("-----%d\n", a);
}
int main()
{
    long data = 110;
    //创建线程
  pthread_t pid;
  int ret = pthread_create(&pid, NULL, Pthread_Task, (void *)data);
  if(ret != 0)
  {
    perror("ptread_create");
    return -1;
  }
  else
  {
    printf("线程创建成功!\n");
  }
}


2、线程的退出

retal: 返回线程结束的状态(void*变量)

让线程退出的三种方法:

  • 线程的任务函数调用完返回退出(直接死),让其他人给这个死的线程回收线程资源.线程调用这个pthread_exit();
    立马死了,让其他人给这个死的线程回收线程资源.
  • 取消线程 pthreada_cancel:只是一个请求(不能保证线程肯定会去退出)
  • 设置线程位分离属性,他死了不需要别人给他收尸。

3、线程资源回收函数

thread: 子线程的id

retval: 子线程结束状态

等待回收子线程的资源(栈空间),作用相当于子线程中的waitpid

pthread_join:默认是堵塞的,自己不能调用pthread_join来回收自己。

4、设置线程分离属性


1)分离属性:子线程的资源由系统回收,线程的资源回收需使用pthread_join来实现,如果该线程运行没有结束,会阻塞主线程,当主线程还要创建新线程来做一些事情,此时主线程就会因为调用pthread_join而被堵塞,就没办法处理其他事务,所以引入线程的分离属性,他不需要主线程回收,在退出系统会自动回收。

线程分离函数:

int pthread_detach(pthread_t thread);

thread:线程id

2)线程创建时选择分离属性-----对pthread_create的第二个参数进行设置

pthread_attr_t *attr

定义一个pthread_attr_t 类型变量attr,然后对这个变量attr 进行初始化 pthread_attr_init()最后设置分离属性。

① 初始化线程属性

int pthread_attr_init(pthread_attr_t *attr);

② 设置分离属性

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

5、线程的取消

1)线程取消函数:pthread_cancel()

2)设置线程取消响应—>是否响应取消信号

3)设置响应取消信号的类型---->立即响应、延时响应
代码段:

#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
struct Data
{
    char pthread_name[10];
};

void *Pthread_Task(void *arg)
{
    //设置线程取消状态---接受取消请求
    int pthread_setcancelstate_ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    if (pthread_setcancelstate_ret != 0)
    {
        perror("pthread_setcancelstate");
        exit(-1);
    }
    while (1)
    {
        struct Data *p = (struct Data *)arg;
        printf("%s\n", p->pthread_name);
        sleep(1);
    }
    pthread_exit(NULL);
}

int main()
{
    pthread_t pid;
    struct Data d1;
    memset(&d1, 0, sizeof(d1));
    strcpy(d1.pthread_name, "hello");
    //创建线程
    int ret = pthread_create(&pid, NULL, Pthread_Task, (void *)&d1);
    if (ret != 0)
    {
        perror("pthread_create");
        exit(-1);
    }
    printf("5s之后发送取消请求\n");
    sleep(5);
    //取消线程
    pthread_cancel(pid);
    pause();
    return 0;
}

压栈和弹栈要配套使用,想让谁响应注册函数,那么就是谁里面写压栈和弹栈。

代码段:

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

//线程注册函数
void Pthread_At_Fun(void *arg)
{
    printf("%s\n", (char *)arg);
}
//线程任务函数
void *Pthread_Task(void *arg)
{   
    //压栈
    pthread_cleanup_push(Pthread_At_Fun, (void *)"死亡闪现");
    printf("三秒之后我将死亡\n");
    sleep(3);
    pthread_exit(NULL);
    //弹栈
    pthread_cleanup_pop(0);  
}
int main()
{
    //创建线程
    pthread_t pid;
    int pthread_create_ret = pthread_create(&pid, NULL, Pthread_Task, NULL);
    if(pthread_create_ret != 0)
    {
        perror("pthread_create");
        exit(-1);
    }
    while(1)
    {
        printf("我看见小线程死亡闪现!\n");
        sleep(1);
    }
    return 0;
}
相关文章
|
10月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
8月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
285 67
|
存储 Linux
认识Linux文件类型和属性
认识Linux文件类型和属性
187 4
|
10月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
181 26
|
10月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
188 17
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
225 0
Linux C/C++之线程基础
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
2月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
149 6
|
5月前
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
306 83
|
2月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
250 0