线程

线程篇(主线程(UI线程),后台线程,线程池线程) 后续不间断增加、提示:以下是本篇文章正文内容,下面案例可供参考总之,不同的线程类型适用于不同的场景,我们需要根据具体的需求来选择合适的线程类型。在使用线程时,我们需要注意线程的生命周期、同步机制、异常处理、性能优化等方面的问题,以保证线程的稳定性和可靠性。 阅读详情
线程概念
  • 线程是在进程内部的,是进程的一个执行分支
  • linux并没有一个专门的类似于进程结构体(pcb)的一个线程描述符,它是用进程描述符来模拟线程,这样做之后,第一个进程创建了对应的pcb、虚拟地址、页表和对应的物理地址,之后在改进程内部创建的线程就和该进程共享这些东西,所以CPU在执行指令的时候并不关心那个是进程,哪个是线程。
  • CPU在各个pcb之间进程来回的切换,这样就形成了多线程
  • linux下所有的进程都可以看成是轻量级进程
  • 每次创建新进程的时候开辟对应的空间,引入线程的概念之后,进程就变成了承担分配空间的任务,而线程是调度的基本单位
  • 如果一个线程退出了,其他的线程都退出了,因为我们的所有线程共享内存资源的,所以我们的一个线程退出了之后,这个线程所开辟的虚拟地址空间就销毁了
线程和进程共享资源和独立资源
  • 共享资源有文件描述表、每种信号的处理方式(SIG_IGN、SIG_DFL或者自定义的信号处理函数)、当前工作目录、用户id和组id
  • 线程 独立资源:因为我们的线程在执行的时候需要来回的切换,这个时候我们需要保存线程的上下文信息,以便之后切换回来的时候可以在刚刚切换出去的地方继续之后,这个时候线程特有的一个资源就是上下文,包括各种寄存器的值、程序计数器和栈指针;每个线程都需要执行一个程序,那么这个程序就有变量等,所有线程就必须有自己独立的栈栈空间;此外线程还有其他的一些特有的内容:线程id,errno变量,信号屏蔽字,调度优先级。
线程创建
#include <pthread.h>

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

函数解析:
thread:这个是线程id,我们需要使用pthread_t 来定义一个线程id编程,以供pthread_create创建进程编号,并将进程 id放在这个变量里面,比如pthread_t pid;
attr:线程属性,这里我们暂时不关心,可以设置为NULL
( * start_routine ):线程执行函数,我们在执行某个线程的时候是通过让线程执行一个函数来执行该线程的,关于这个函数的设计,我们也要设计符合要求的函数,函数的返回值要是void*,函数的参数也是void*,这里我们给出一个函数的示例

void* pthread_run(void* arg)
{
    ......
    return (void*)1;
}

我们的这个函数要在main函数的外面定义,我们在函数中传参的时候直接使用函数名就好了
arg:这个是前面一个函数的参数,这里也暂时设置为NULL
返回值:成功返回0,失败返回错误编号

补充:这里注意我们只要使用pthread的相关函数,在编译的选项中加上

获取线程id
#include <pthread.h>

       pthread_t pthread_self(void);

和getpid的使用类似,注意这个返回值是无符号整型

线程等待
#include <pthread.h>

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

参数解析
thread:线程id
retval:这个是我们需要提前定义的一个二级指针变量,比如我们定义了一个void* join,在使用的时候可以参数就是&join,这个join获取其实就是线程 函数中返回的那个值,因为返回的是void*,所以我们这里要定义一个二级指针去接受它

线程终止
#include <pthread.h>

       void pthread_exit(void *retval);

参数解析
retval:这里我们可以传入的参数是(void*)12;这和使用return返回时一样的

线程取消
#include <pthread.h>

       int pthread_cancel(pthread_t thread);

参数解析:
thread:线程id,我们可以使用该函数终止自己,也可以终止其他的线程,自己终止自己的时候传递的参数就是pthread_self();

线程参数传递

这里还是要回到线程创建那里,看下面的线程创建的函数

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

上面解释过,这个函数的第一个参数是一个线程id,第二个参数可以暂时设置成NULL,第三个参数是一个线程函数,这个函数的返回值是void*,参数是void*,虽然参数是void*但是不代表我们不能传递参数,pthread_create这个函数的第四个参数就可以用来给我们的线程函数传递参数使用,比如这里我们想传递一个整型变量a,但是第四个参数只能是void ,在这个时候,我们可以直接使用(void )a;进行 参数传递。然后在线程函数中,直接使用(int)arg,进行函数的使用,因为在线程函数中,那个参数只能是(void *)arg的,这个arg就是我们在使用 pthread_create时传递的第四个参数。如果我们想传递多个参数怎么办呢,这个时候我们测办法是,先定义一个结构体,然后把它强转成一个结构体的指针进行使用。

这里介绍两个指令,用于查看线程的

ps aux | grep xxx(程序名称)
ps -aL | grep xxx(程序名称)
ps -aL | head

查看进程退出结构

echo $?

查找

grep -ER ‘查找名’ …

ER表示递归查找,…表示查找的路径

附上代码

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

void* pthread_run(void* arg)   //返回值void*,参数void*
{
    pthread_cancel(pthread_self());
    printf("进程id  :%d   线程id:%u\n",getpid(),pthread_self());
    printf("i am thread!\n");
    sleep(3);
    //return (void*)1;    //返回值void*
    pthread_exit((void*)123);  //这里的返回作用和上面的return的效果是一样的
}


int main()
{
    pthread_t pid;   //定义一个线程地址变量,供pthread_create使用
    int ret = pthread_create(&pid,NULL,pthread_run,NULL);   //&pid:当pthread_create执行之后会把pid赋值,NULL线程属性,pthread_run线程函数,NULL:函数参数
    //pthread_cancel(pid);
    sleep(5);
    void* join;    //这里的jion是我们设置的一个变量,用来记录返回的一些信息的,我们可以通过其他的一些宏函数之类的来获取保存在join里面的相关的信息
    pthread_join(pid,&join);
    printf("进程等待%d\n",join);
    printf("进程id  :%d  线程id :%u\n",getpid(),pthread_self());
    printf("%d\n",ret);
    return 0;
}
Linux 线程:使用&管理线程、多线程、分离线程 阅读详情

相关推荐

线程池的线程是如何复用的

进程和线程的关系相信大家都知道,这里我就不做过多的解释了,既然一个进程是由多个线程组成的,那么线程池又是由若干个线程队列组成的,在并发量比较高的情景下,我们通常会去创建线程池就执行任务,而不单一的创建多个线程去执行任务,因为线程的创建的一系列动作,是需要资源开销的,如果频繁的对线程创建销毁,其实本身是一种很浪费资源的,就更谈不上提高效率了。

m0_71777195的博客 2537

线程基础概念总结

一些线程基础概念

qq_36534594的博客 423

前台线程和后台线程、用户线程和守护线程

一、Java 分为两种线程:用户线程和守护线程 所谓守护线程是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因 此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。 守护线程和用户线程的没啥本质的区别:唯一的不同之处就在于虚拟机的离开:...

程序员世杰 2745

线程基础知识点

一、概念 进程并不执行任务,只是为线程提供空间和资源,线程才是执行任务的实体。

874

Windows系统的Mamba环境配置详细教程(状态空间模型)

causal_conv1d也是安装mamba的依赖必须库。安装完成后,通过pip list可以查看到安装的库。Triton是安装mamba的依赖,需要先安装。上述工作准备好后,按下面步骤安装。直接根据离线文件安装即可。是自己的虚拟环境名字。

2301_77831163的博客 3677

华为私有云HCS 8.1.1实战:从镜像制作到云主机发放全流程指南

本文详细解析了华为私有云HCS 8.1.1从镜像制作到云主机发放的全流程实战指南。内容涵盖制作标准化QCOW2镜像、配置云主机规格与主机组、规划外部网络,以及在运营面为租户初始化资源、配置审批流与产品目录。最后,通过用户视角演示了从创建VPC网络到申请、审批并最终绑定EIP访问云主机的完整操作步骤,为运维人员和架构师提供了一套清晰、可落地的HCS部署与管理实践方案。

weixin_29305313的博客 1128

linux 线程有自己独立的内核栈(内核栈中存储着pcb)吗?

疑问:首先,我们知道所有线程共享主线程的虚拟地址空间(current->mm指向同一个地址),且都有自己的用户态堆栈(共享父进程的地址空间,再在里面分配自己的独立栈,默认2M)。这是毫无疑问的,但还有一点我没搞明白,内核栈是共享还是独立的? 回答:独立的。理由:要不然内核栈对应的thread_info中的tast_struct(pcb进程控制块)没有办法与每个线程对应起来,因为现在已经有多个task_struct了,但保存内核栈的thread_info(其实是thread_union联合体)中只能保存

niusi1288的博客 4222

Wordpress实战之第二章安装wordpress 软件需要的软件

使用下载并安装phpstudy面版工具 wget -O install.sh?https://notdocker.xp.cn/install.sh?&& sudo bash install.sh 2.安装成功如下 ==============运行状态========================= webpanel stop phpstudy running =================...

安全参透之旅 612

线程间有哪些资源是不可以共享的?

线程的大部分内容是可以被共享的,这里主要了解线程间有哪些内容是不可以被共享的。

challenglistic的博客 5646

pyinstaller+scrapy打包出现错误:OSError: could not get source code

错误如下: Traceback (most recent call last): File "scrapy\utils\defer.py", line 55, in mustbe_deferred File "scrapy\core\spidermw.py", line 60, in process_spider_input File "scrapy\core\scraper.py", line 152, in call_spider File "scrapy\utils\misc.py

kin的博客 1759

Python头歌实验题目(2024版)

武汉理工大学头歌平台实验题目

2401_84152595的博客 2万+

关于进程和线程知识点梳理(万字文章)

最近在看《现代操作系统》这本书的第二章“进程和线程”,同时结合网上查找资料的学习,将进程和线程以及常见的一些问题整理如下: 进程 概念 一个进程是一个正在执行程序的实例的抽象,包括程序计数器、寄存器和程序变量的当前值等 操作系统的其他所有内容都是围绕着进程展开的 进程是操作系统进行资源分配和调度的一个基本单位 多道程序设计 多道程序设计是在计算机内存中同时存放几道相互独立的程序,使它们在管理程序控制之下,相互穿插的运行,宏观上让人感觉程序是并行执行的、微观上其实是串行执行的: CPU 从一个进程切换到

zdplife的专栏 433

ANPC三电平拓扑:两种调制方式解析

ANPC结构是基于“I”型NPC结构(下面讲NPC如不特殊说明,均指的是“I”型结构NPC)发展出来的一种改进型。我们在讲NPC结构的时候会谈到他的一个缺点就是损耗分布不均匀,会导致温升不均衡,进而限制模块的功率输出能力。而ANPC结构由于多了两个开关管以及相应的两个中性点换流回路(如下图),可以更加灵活任意的配置开关管可以使损耗没有那么的不均衡,从而能一定程度上提高模块的输出功率。ANPC拓扑结构图以及增加的环流回路。

IOTBOT的博客 9485

线程及线程池

本文章主要讲解线程及线程池部分的相关知识

2301_80365603的博客 1961

计算机组成原理(第三版)唐朔飞-第七章指令系统-课后习题

机器字长是指CPU一次能处理数据的位数通常与CPU的寄存器位数有关。指令字长是指机器指令中二进制代码的总位数。存储字长是指存储单元中存放二进制代码的总位数。三者可以相等也可以不等视不同机器而定。答:OP(4位)A1(6位)A_1(6位)A1​(6位)A2(6位)A_2(6位)A2​(6位)设二地址指令格式为该指令系统的基本格式,4位操作码共有16种编码,其中13种用来定义二地址指令,还剩3种可用作扩展标志。一地址指令条数=3∗26=192。

weixin_45735391的博客 7万+

SAP ABAP OData 的四种开发方式

摘要:SAP开发中CDS视图转OData服务的四种方案演进:1)7.40+版本需手动映射数据源;2)7.50+可直接引用CDS视图自动生成服务;3)7.50+通过@OData.publish注解声明式发布;4)7.54+采用服务定义与绑定实现协议解耦。新版本推荐使用最新方案,旧系统可选传统方式,整体呈现开发简化、架构解耦的技术演进趋势。(150字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 862

一键了解线程、线程安全、线程池

一键了解线程、线程安全、线程池

HKTTT_的博客 2038

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

linux线程详解:线程概念、线程调度、线程安全、线程模型

(1)线程的组成:线程ID、当前指令指针(PC)、寄存器集合、堆栈;(2)一个进程包含一个或者多个线程,其中进程的大部分资源(代码段、数据段、堆段、打开文件/信号等)都是线程间共享的,线程会保留一部分私有数据(寄存器、栈);

weixin_42031299的博客 3583

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

多线程,线程池,线程的创建,线程池的参数

​ 进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。线程也被称为轻量级进程,线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其它线程共享该进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

weixin_44797327的博客 1302

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

多线程——线程实现、线程状态、线程同步、线程通信、线程池

多线程一、线程1.普通方法调用和多线程2.程序、进行、线程二、线程创建1.继承Thread类2.实现Runable接口3.实现Callable接口4.静态代理模式5、Lamda表达式三、线程状态1.线程状态2.线程方法3.线程停止4.线程休眠sleep5.线程礼让5.join6.线程状态观测7.线程优先级8.守护(daemon)线程四、线程同步1.并发与并行2.线程同步——等待机制2.1 队列 和 锁2.2 线程同步2.3 同步方法2.4 同步块3.死锁4. Lock锁 一、线程 1.普通方法调用和多线程

weixin_44090845的博客 3771

JAVA线程、线程池解析

是操作系统能够进行的最小单位,它被包含在进程之中,是进程中的实际运作单位。进程是资源分配的基本单位,它拥有自己独立的地址空间和各种资源;而线程是处理机调度的基本单位,它只能和其他线程共享进程的资源,而。线程的上下文切换速度比进程快。

柔丽君的博客 1413

易语言创建线程挂起线程恢复线程销毁线程

线程创建CreateThread,线程挂起SuspendThread,线程恢复ResumeThread,线程销毁TerminateThread,都是kernel32的命令,我们自己封装这些线程的命令,就是便于我们理解他们的工作机制。 API源码: .版本 2 .DLL命令 恢复线程, 整数型, "kernel32", "ResumeThread", , 恢复线程 .参数 hThread, 整数型, , 线程的句柄 .DLL命令 销毁线程, 整数型, "kernel32", "Termi

511遇见 1万+

线程 - 线程优缺点、线程自有和共享的数据、多线程使用公共空间、线程分离、线程库对线程的管理

在上面的【四、2. 线程自有的数据】部分,我们提及了线程有独立栈结构,现在我们看到它了, 线程的栈结构是在库中维护的,每个线程都有自己的独立栈结构,主线程使用的是地址空间中的栈空间,叫主线程栈。多线程切换有成本,像上面的计算密集型应用,线程过多可能会有较大的性能损失(增加了额外的同步和调度开销,而可用资源不变)。而进程创建的时空成本是较高的,有各种数据结构的创建,数据的加载。让两个线程进同一个线程函数,打印同一个临时变量的地址,是不一样的,说明使用的是不同的栈结构。而线程占用的都是一份的。

addicted_to的博客 1384

Linux-多线程2 ——线程等待、线程异常、线程退出、线程取消和线程分离

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档。

fengjunziya的博客 1430

在子线程中创建子线程及线程查看方法

小结:我们看到,son线程的退出,并没有影响到孙线程的运行,因为进程并未退出。 以上述方式一的形式查看线程:1)同一进程中的线程是平等的,没有父子之分。当然也包括所谓的主线程、在主线程中创建的线程、在所谓的子线程中创建的线程。线程既然是平等的,只要进程不退出,倘若son线程退出,我们看到不会影响到孙线程的运行。2)孙线程在子线程中创建,可以理解为,启动孙线程的顺序点是在此时,而并非在主线程中。也就是说,我们可以在任意我们需要创建一个平行任务的地方,创建一个子线程,而并非得在主线程中创建。3)线程函数,其实,

modi000的博客 3070

[线程]等待一个线程, 获取当前线程引用,休眠当前线程, 线程的六种状态

我们知道, 多个线程的调度顺序是无序的, 谁先被调度不确定, 谁先结束也不确定, 所以我们引入线程等待, 可以控制线程结束的先后顺序 上述代码的thread 和 main 之间的结束顺序是不确定的如果我们希望让代码中的t先结束, main后结束, 就可以在main中使用线程等待join(join也要抛异常, 和sleep抛出的异常相同) 我们先修改一下代码, 让thread打印六次, main打印三次, 此时一定是main先结束, 再打印几次thread后, thread才结束 接下来我们加入join 注

m0_73992740的博客 1231
上一篇: IPC--共享内存
下一篇: 地址解析协议ARP
NeilZhy
博客等级 码龄11年 175粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值