文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Linux线程:创建(pthread_create),等待(pthread_join),退出(pthread_exit)

2023-09-04 13:30

关注

目录

一 线程说明

①线程与进程:

②线程优点:

③线程缺点:

二 线程开发API概要

三 线程控制流程

① 线程创建(pthread_create)

② 线程退出(pthread_exit)

③ 线程等待(pthread_join)

④ 线程脱离(pthread_detach)

⑤ 线程ID获取(pthread_self)

四 完整代码示例


一 线程说明

Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。 Linux 把所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表示线程。线程只被视为一个与其他进程共享某些资源的轻量级进程。所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)
 

①线程与进程:

①所有的轻量级进程(线程)都是在进程的内部运行;

进程是资源分配的最小单位,线程是程序执行的最小单位;

③进程具有独立性,可以有部分共享资源(比如:管道,IPC资源);

④线程大部分资源是共享的(例如:代码、进程数据、文件描述符、信号处理方式),可以有部分资源是私有的(例如:PCB、栈、上下文);

★ 每个线程是有自己的独立栈,保存线程运行时形成的临时数据;上下文中保存的是CPU调度时存放在寄存器中的临时数据。

线程进程
标识符类型pthread_tpid_t
获取idpthread_self()getpid()
创建pthread_create()fork()


 

②线程优点:

① 创建一个新线程的代价要比创建一个新进程小得多;

② 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多;

③ 线程占用的资源要比进程少很多;

④ 能充分利用多处理器的可并行数量;

⑥ 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务;

⑦ 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现;

⑧ I/O密集型应用,为了提高性能,将I/O等待就绪操作重叠。线程可以同时等待不同的I/O操作;
 

③线程缺点:

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

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

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

④ 编程难度提高:编写与调试一个多线程程序比单线程程序困难得多。

二 线程开发API概要

多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁。条件操作有 5 种操作:创建,销毁,触发,广播和等待。其他的一些线程扩展概念,如信号灯等,都可以通过上面的三个基本元素的基本操作封装出来。详细请见下表:

三 线程控制流程

本篇文章先说明线程的创建,等待,退出这三个API;

① 线程创建(pthread_create)

#include int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);//返回值:成功返回0,失败返回错误编号

pthread_t *thread:线程ID,由函数pthread_self()获取,类似获取进程pid使用getpid()函数;

const pthread_attr_t *attr:用于定制各种不同的线程属性,暂可以把它设置为NULL,以创建默认属性的线程;

void *(*start_routine) (void *):线程中执行函数。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg

void *arg:执行函数中中参数。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入

② 线程退出(pthread_exit)

单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:

 1)线程只是从启动例程中返回,返回值是线程的退出码。

 2)线程可以被同一进程中的其他线程取消。

 3)线程调用pthread_exit:

#include int pthread_exit(void *rval_ptr);

rval_ptr:是一个无类型指针,与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join函数访问到这个指针。

③ 线程等待(pthread_join)

#include int pthread_join(pthread_t thread, void **rval_ptr);// 返回:若成功返回0,否则返回错误编号

调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。如果例程只是从它的启动例程返回,rval_ptr将包含返回码。如果线程被取消,由rval_ptr指定的内存单元就置为PTHREAD_CANCELED。①可以通过调用pthread_join自动把线程置于分离状态,这样资源就可以恢复。如果线程已经处于分离状态,pthread_join调用就会失败,返回EINVAL。②如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。

④ 线程脱离(pthread_detach)

一个线程或者是可汇合(joinable,默认值),或者是脱离的(detached)。当一个可汇合的线程终止时,它的线程ID和退出状态将留存到另一个线程对它调用pthread_join。脱离的线程却像守护进程,当它们终止时,所有相关的资源都被释放,我们不能等待它们终止。如果一个线程需要知道另一线程什么时候终止,那就最好保持第二个线程的可汇合状态。

pthread_detach函数把指定的线程转变为脱离状态

#include int pthread_detach(pthread_t thread);// 返回:若成功返回0,否则返回错误编号

 本函数通常由想让自己脱离的线程使用,就如以下语句:

pthread_detach(pthread_self());

⑤ 线程ID获取(pthread_self)

#include pthread_t pthread_self(void);// 返回:调用线程的ID

四 完整代码示例

#include #include #include #include void *func(void *arg)//定义执行函数func{        static int ret = 10;//定义tid2线程退出码        printf("tid2:%lu\n",pthread_self());//        printf("pid2:%d\n",getpid());//进程id        pthread_exit((void *)&ret);//结束线程tid2}int main(){        int *pret;        pthread_t tid1;//定义主线程        pthread_t tid2;//定义子线程        pid_t pid1;//进程id        pid_t pid2;//进程id        printf("tid1:%lu\n",pthread_self());//打印主线程id        printf("pid1:%d\n",getpid());//打印进程id        pthread_create(&tid2,NULL,func,NULL);//创建线程tid2        pthread_join(tid2,(void **)&pret);//等待线程tid2退出,获取退出状态码        printf("tid2 exit retval:%d\n",*pret);//打印线程退出的状态码        return 0;}

代码执行结果:进程id一样,线程id不一样,说明在同一个进程中执行了两条不同的线程,获取到已经定义好的退出状态码10。

dhw@dhw-virtual-machine:~/thread$ ./a.outtid1:140212273063744pid1:6791tid2:140212273059392pid2:6791tid2 exit retval:10

来源地址:https://blog.csdn.net/m0_74985965/article/details/128815940

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯