首页 > 系统相关 >【Linux】初识线程

【Linux】初识线程

时间:2024-07-19 22:56:24浏览次数:19  
标签:thread 创建 void Linux 初识 线程 pthread 进程

目录

什么是线程

线程的优点 

线程的缺点

线程异常 

线程接口

创建线程

线程等待

线程终止或者取消

获取当前线程id

分离线程


什么是线程

        在一个程序里的一个执行路线就叫做线程,更准确的定义是:线程是“一个进程内部的控制序列”。

  • 一切进程至少都有一个执行线程。
  • 线程在进程内部运行,本质是在进程地址空间运行。
  • 在Linux系统中,在CPU视角中,看到的PCB都要比传统的进程更加轻量化。

线程的优点 

  • 创建一个新线程的代价要比创建一个新进程小得多
  • 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
  • 线程占用的资源要比进程少很多
  • 能充分利用多处理器的可并行数量
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  • I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

线程的缺点

1.性能损失

        一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型 线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的 同步和调度开销,而可用的资源不变。

2.健壮性降低 

        编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。

3.缺乏访问控制

 进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。

4.编程难度提高

 编写与调试一个多线程程序比单线程程序困难得多

线程异常 

  • 单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃
  • 线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出

线程接口

        头文件#include <phread.h>,这个库属于第三方库,也是原生线程库,linux中编写多线程代码都需要使用这个库。

        操作系统内部没有线程的概念,只有轻量级进程,因此我们创建线程需要使用pthread线程库。phtread线程库对操作系统创建轻量级进程接口进行封装,为用户提供直接创建线程的接口。

轻量级进程接口 clone(回调函数,独立栈)

综上所述,线程的概念是库给我们维护的, 这个原生线程库是动态库,因此需要加载到内存中,给每个线程分配一个独立栈的内存空间。

查看所有线程 

ps -aL

通过LWP(light weight process)区分不同的执行流 。PID等于LWP,就表明该线程是主线程,不相等的话,就代表该线程是被创建出来的。

创建线程

int pthread_create(pthread_t *thread,

                                const pthread_attr_t *attr,

                                void *(*start_routine) (void *),

                                void *arg);

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

  • pthread_t *thread:输出型参数,thread id。
  • const pthread_attr_t *attr:线程属性,一般不管,设置为nullptr。
  • void *(*start_routine) (void *):返回值是void* ,参数是void* 的函数指针,作用是传入要该线程执行的函数方法。

        void 不能定义变量,因为他无法确定大小,但是void* 可以,用void* 可以接收任意类型的。

  •  void *arg:创建线程成功,新线程回调线程函数的时候,需要参数,这个参数就是给线程函数传递的,也就是第三个函数指针所需要的参数。

当一个函数被多个执行流同时执行,则称该函数被重入了

线程等待

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

  • pthread_t thread:要等待的线程id。 
  • void **retval:接收所等待线程的返回值。

线程终止或者取消

其中exit是用来终止进程的,不能用来终止线程。

终止线程除了return以外,还有一个pthread_exit((void*)100),这里所说的终止线程,是在线程执行的方法函数中。

除了这两种方法以外,还可以在主线程中通过pthread_cancel(tid)取消线程

获取当前线程id

pthread_t pthread_self(void);

返回值为当前线程id

每个线程的库(phtread库)级别的tcb的起始地址叫做线程的tid

定义一个每个线程私有的全局变量

__thread int g_val = 100;

__thread只能定义内置类型,不能用来修饰自定义类型

分离线程

        默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。

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

int pthread_detach(pthread_t thread);

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

pthread_detach(pthread_self());

 joinable和分离是冲突的,一个线程不能既是joinable又是分离的。

标签:thread,创建,void,Linux,初识,线程,pthread,进程
From: https://blog.csdn.net/lzb_kkk/article/details/140326458

相关文章

  • Linux学习笔记day01-shell命令、vim编辑器
    **1.Linux基础**   1)特点:免费、开源、安全可靠、可裁剪、可移植、将所有硬件都识别视为文件来处理   2)Linux与Windows文件存储区别:         windows:磁盘分区管理         Linux:从根目录出发3)基本目录:    bin:二进制文件  ......
  • 理解进程,线程,协程
    为什么需要进程,线程,协程?举个例子,比如:我们gorunmain.go,启动一个go程序,从磁盘读取可执行文件,将CPU要执行的命令加载到内存中,然后CPU就一直:1.读取内存指令,2.执行指令,循环往复。那我们从磁盘读取的可执行文件,读到内存,他放在什么地方呢?我们需要找一个结构体来记录这些东西......
  • Linux内存从0到1学习笔记(8.19 ION (一))
    一,ION简介ION(InterprocessCommunicationOverNon-ContiguousMemory)即“跨进程非连续内存通信”。是Android系统中负责内存管理的关键子系统,由Google在Android4.0ICS中引入,旨在解决当时Android设备中存在的多样化内存管理机制所带来的问题,也就是用归一化的思想来解......
  • 线程池(C++11)
    已经有现成的实现,本博客摘抄讲解附源码链接。参考的博客质量已经非常高,避免找来找去。1、避免频繁创建、销毁线程,实现复用。思路如下:2、线程函数多种多样,如何封装成统一的函数类型void()第一次封装我们使用bind()函数将多个参数的函数封装为没有形参的package_task对象,因为p......
  • 【发现】Rust-for-Linux_的成败得失
    https://www.usenix.org/system/files/atc24-li-hongyu.pdfRFL(RustforLinux)从2013年开始筹备进入Linux内核,自从2022年以来,合并了20K行代码到Linux主线,成为了Linux除了ebpf和io_uring之外最活跃的子系统。本文主要回答了3个问题:RFL现状如何:RFL的代码主......
  • Linux中进程间通信--匿名管道和命名管道
        本篇将会进入Linux进程中进程间通信,本篇简要的介绍了Linux中进程为什么需要通信,进程间通信的常用方式。然后详细的介绍了Linux进程间的管道通信方式,管道通信分为匿名管道和命名管道,本篇分别介绍了其实现的原理,以及使用Linux中的系统调用,用代码实现了这两......
  • Linux驱动开发-06蜂鸣器和多组GPIO控制
    一、控制蜂鸣器1.1控制原理 我们可以看到SNVS_TAMPER1是这个端口在控制着蜂鸣器,同时这是一个PNP型的三极管,在端口输出为低电平时,蜂鸣器响,在高电平时,蜂鸣器不响 1.2在Linux中端口号的控制        gpiochipX:当前SoC所包含的GPIO控制器,我们知道I.MX6UL/I.MX6ULL......
  • Linux配置jdk环境变量
     首先再官网下载jdk1.8下载地址:JavaDownloads|Oraclehttps://www.oracle.com/java/technologies/downloads/ 然后通过Mobaxtrem将文件拖到linux操作系统中,我的是放在这个位置中的 解压tar-zxvfjdk-8u291-linux-x64.tar.gz 然后我们现在去配置环境变量:我们首......
  • 秒懂LINUX之初识指令
    目录一.ls指令​编辑1.1ls-l1.2ls-a二.pwd指令三.cd指令3.1cd..3.2 cd/home/litao/linux/ 3.3cd../day02/3.4cd~3.5cd-四.touch指令五.mkdir指令5.1 mkdir–p六.rmdir指令&&rm指令6.1rmdir-p6.2rm-f6.3rm-r6.4rm-rf*......
  • 【Linux】Linux进程揭秘:从理论到实践的深度探索之旅
    目录前言:操作系统简介概念设计目的理解进程:程序的执行之魂进程和程序的联系与区别 描述进程-PCB进程的标识符 进程状态 状态转换僵尸进程孤儿进程前言:操作系统简介概念操作系统(英语:OperatingSystem,缩写:OS)是一组主管并控制计算机操作、运用和运行硬件、软......