linux操作系统之线程

1.线程概念

  • 线程是一个轻量级进程,每一个线程都属于一个进程

  • 进程是操作系统资源分配的最小单位,而线程是CPU任务调度的最小单位

  • 线程是一个任务执行的过程,包括创建,调度,消亡

    • 创建:线程空间位于进程空间,进程中的线程,栈区独立,并共享进程中的数据区,文本区,堆区

    • 调度:宏观并行,微观串行,与进程调度保持一致

    • 消亡:线程结束后,需要回收线程空间

2.多线程与多进程区别

  • 执行效率:多线程执行效率高,创建速度快,任务切换快, 多进程效率低;

  • 通信:线程可以共享空间,直接通信(可以使用全局变量), 进程空间独立,不能直接通信(通信必须使用:管道,信号,共享内存...)

  • 安全性:多线程不安全(一个进程异常结束可能会导致进程结束,使其他的线程无法执行)

  • 资源消耗:相比于进程,线程的内存消耗通常会更小,因为线程共享进程的大部分内存空间和资源

3.线程实现接口

  • 线程库

    • pthread_create

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

      • 创建一个线程

        • 注意:一次pthread_create执行只能创建一个线程, 每个进程至少有一个线程称为主线程,主进程退出则所有创建的子线程都退出,主线程必须有子线程同时运行才算多线程程序,线程id是线程的唯一标识,是CPU维护的一组数字。

        • 参数:thread:存放线程ID空间首地址,attr:线程的属性(默认NULL),start_routine:线程入口函数地址(函数指针,指向线程任务函数),arg:给线程函数的参数

    • pthread_self

      • pthread_t pthread_self(void);

        • 获取当前线程的线程id
    • pthread_exit

      • void pthread_exit(void *retval);

        • 子线程自行退出

          • 参数: retval 线程退出时候的返回状态,临死遗言。(不能是局部变量的地址)
    • pthread_join

      • int pthread_join(pthread_t thread, void **retval);

        • 通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞

          • 参数:thread 要回收的子线程tid,retval 要回收的子线程返回值/状态
    • pthread_cancel

      • int pthread_cancel(pthread_t thread);

        • 请求结束一个线程

          • 参数:thread 请求结束一个线程tid

4.线程属性

  • 1.可结合性

    • 能被其他线程回收和杀死的线程具有可结合性,在没有被其他线程回收之前,其资源不释放;

    • 使用pthread_join()函数回收,线程默认具有可结合性

  • 2.分离属性

    • 不能被其他线程回收或杀死的线程具有分离属性,其存储资源在终止时被系统自动释放(类似于孤儿进程)

    • 线程结束后空间自动被操作系统回收,无需调用回收线程的接口函数

    • 线程无法在线程结束实现同步,无法回收线程结束状态

    • 设置分离属性,目的线程消亡,自动回收空间

    • int pthread_attr_init(pthread_attr_t *attr);

      • 功能:初始化一个attr的变量
    • int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

      • 功能:把一个线程设置成相应的属性

      • attr,属性变量,有init函数初始化

      • PTHREAD_CREATE_JOINABLE:可结合性

      • PTHREAD_CREATE_DETACHED:设置分离属性

    • pthread_attr_destroy

      • int pthread_attr_destroy(pthread_attr_t *attr);

        • 销毁线程属性

5.线程控制

  • 互斥

    • 互斥机制:

      • 互斥机制 ===》互斥锁 ===》解决多线程操作共享空间引发的资源竞争问题。

      • 在多线程中对临界资源的排他性访问。

    • 多个线程在操作临界资源时存在资源竞争问题;

    • 临界资源:多个线程可以同时访问到的资源,如:共享变量,全局变量,共享内存等。。。

    • pthread_mutex_t mutex;

    • 初始化锁

      • int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex attr_t *attr);

        • 将已经定义好的互斥锁初始化。
    • 加锁

      • int pthread_mutex_lock(pthread_mutex_t *mutex);

        • 用指定的互斥锁开始加锁代码

        • 加锁后的代码到解锁部分的代码属于原子操作,在加锁期间其他进程/线程都不能操作该部分代码,如果该函数在执行的时候,mutex已经被其他部分使用则代码阻塞

    • 解锁

      • int pthread_mutex_unlock(pthread_mutex_t *mutex);

        • 将指定的互斥锁解锁,解锁之后代码不再排他访问,一般加锁解锁同时出现。
    • 销毁

      • int pthread_mutex_destroy(pthread_mutex_t *mutex);

        • 使用互斥锁完毕后需要销毁互斥锁
  • 同步

    • 有一定先后顺序的对资源的排他性访问。

      • 原因:互斥锁可以控制排他访问但没有次序。
    • 信号量的定义

      • sem_t sem;
    • 信号量的初始化

      • int sem_init(sem_t *sem, int pshared, unsigned int value);

        • 将已经定义好的信号量赋值,sem 为要初始化的信号量, pshared = 0 ;表示线程间使用信号量,!=0 ;表示进程间使用信号量,value 信号量的初始值,一般无名信号量
    • 信号量操作

      • 申请一个信号量

        • int sem_wait(sem_t *sem);
      • 释放一个信号量

        • int sem_post(sem_t *sem);
      • 信号量的销毁

        • int sem_destroy(sem_t *sem);
  • to be continue...

相关推荐
陌小呆^O^2 分钟前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp
C++忠实粉丝2 分钟前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp
Gu Gu Study9 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
量子网络20 分钟前
debian 如何进入root
linux·服务器·debian
时光の尘24 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
我们的五年28 分钟前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
-一杯为品-33 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
以后不吃煲仔饭37 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师38 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
前端拾光者42 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化