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

这篇具有很好参考价值的文章主要介绍了Linux线程:创建(pthread_create),等待(pthread_join),退出(pthread_exit)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一 线程说明

①线程与进程:

②线程优点:

③线程缺点:

二 线程开发API概要

三 线程控制流程

① 线程创建(pthread_create)

② 线程退出(pthread_exit)

③ 线程等待(pthread_join)

④ 线程脱离(pthread_detach)

⑤ 线程ID获取(pthread_self)

四 完整代码示例


一 线程说明

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

①线程与进程:

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

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

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

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

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

线程 进程
标识符类型 pthread_t pid_t
获取id pthread_self() getpid()
创建 pthread_create() fork()


 

②线程优点:

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

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

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

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

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

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

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

③线程缺点:

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

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

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

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

二 线程开发API概要

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

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

三 线程控制流程

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

  • 使用-pthread编译和链接。

① 线程创建(pthread_create)

#include <pthread.h>

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 <pthread.h>
int pthread_exit(void *rval_ptr);

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

③ 线程等待(pthread_join)

#include <pthread.h>
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 <pthread.h>
int pthread_detach(pthread_t thread);
// 返回:若成功返回0,否则返回错误编号

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

pthread_detach(pthread_self());

⑤ 线程ID获取(pthread_self)

#include <pthread.h>
pthread_t pthread_self(void);
// 返回:调用线程的ID

四 完整代码示例

#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

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。文章来源地址https://www.toymoban.com/news/detail-480479.html

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

到了这里,关于Linux线程:创建(pthread_create),等待(pthread_join),退出(pthread_exit)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux pthread线程操作 和 线程同步与互斥操作

    在Linux系统中玩线程,使用pthread,这篇博客记录如何 创建线程 和 使用线程 和线程的 同步 与 互斥 。 还有一份nginx线程池的代码供大家阅读学习! 目录 一、简介 什么是线程 线程的优点、缺点 线程的应用场合 二、线程的使用 1.  创建线程 - pthread_create 2.  线程的终止 - pt

    2024年02月02日
    浏览(23)
  • 【Linux系统编程:线程】 线程控制 -- 创建、终止、等待、分离 | 线程互斥与同步 | 互斥量与条件变量 | 生产者消费者模型 | 线程池 | STL/智能指针与线程安全 | 读者写者模型

    写在前面 本文重点: 了解线程概念,理解线程与进程区别与联系。 学会线程控制,线程创建,线程终止,线程等待。 了解线程分离与线程安全。 学会线程同步。 学会使用互斥量,条件变量,posix 信号量,以及读写锁。 理解基于读写锁的读者写者问题。 一、线程概念 💦

    2024年02月04日
    浏览(47)
  • Linux线程(4)——pthread_detach()自动回收线程资源

    分离线程                 默认情况下,当线程终止时,其它线程可以通过调用 pthread_join()获取其返回状态、回收线程资源,有时,程序员并不关心线程的返回状态,只是希望系统在线程终止时能够自动回收线程资源并将其移除。在这种情况下,可以调用 pthread_detach

    2024年02月03日
    浏览(28)
  • Linux多线程编程- pthread_self()

    pthread_self() 函数是 POSIX 线程库的一部分,它提供了一个非常简单的功能:获取当前线程的唯一标识符。这个标识符是 pthread_t 类型的,通常是一个无符号的长整型值,不过具体的类型是由实现定义的,这意味着它可以在不同的操作系统上有不同的表示。 这个标识符对于调试多

    2024年02月06日
    浏览(25)
  • linux_设置线程属性-pthread_attr_t结构体-设置线程分离态-修改线程栈的大小-NPTL

    接上一篇:linux_线程分离pthread_detach函数-线程取消pthread_cancel函数-线程相等pthread_equal函数   本次来分享linux线程的属性设置,线程属性主要是一个结构体 pthread_attr_t ,这个结构体中的成员就是线程的属性了,需要通过一系列的函数来修改,话不多说,上菜: 此博主在CSD

    2024年02月02日
    浏览(30)
  • 【Linux】详解线程控制 -- 线程用法 | 线程等待 | 线程ID及地址空间布局

    (关于 用户 → 库 → OS :具体可看下面线程地址空间布局) 这个 clone 我们不用,这是OS提供给第三方库所用的接口 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“ pthread_ ”开头的,要使用这些函数库,要通过引入头文 pthread.h ,链接这些线程函数库时要

    2024年02月15日
    浏览(43)
  • Linux进程控制【创建、终止、等待】

    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Good judgment comes from experience, and a lot of that comes from bad judgment. 好的判断力来自经验,其中很多来自糟糕的判断力。 进程 创建后,需要对其进行合理管理,光靠

    2024年02月02日
    浏览(30)
  • 【Linux】进程控制(创建、终止、等待)

    环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【Linux】进程理解与学习Ⅰ-进程概念 【Linux】进程理解与学习Ⅱ-进程状态 【Linux】进程理解与学习Ⅲ-环境变量 【Linux】进程理解与学习Ⅳ

    2023年04月16日
    浏览(47)
  • [Linux]进程控制详解!!(创建、终止、等待、替换)

            hello,大家好,这里是bang___bang_,在上两篇中我们讲解了进程的概念、状态和进程地址空间,本篇讲解进程的控制!!包含内容有进程创建、进程等待、进程替换、进程终止!! 附上前2篇文章链接: Linux——操作系统进程详解!!(建议收藏细品!!)_bang___ba

    2024年02月15日
    浏览(31)
  • linux入门之进程控制(上)进程创建,进程等待

    目录 一、进程创建 1.fork函数 2.fork函数返回值 3.写时拷贝 4.fork常规用法 5.fork调用失败原因 二、进程终止 1.进程退出场景 2.进程常见退出方法 2.1_exit函数(直接调用内核) 2.2 exit函数 2.3return退出 三、进程等待 1.进程等待必要性 2.进程等待方法 2.1 wait方法 2.2 waitpid方法 2.3获取

    2024年02月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包