• 线程(上篇):线程的创建


     

    "没有人会一直活在过去,除非他的生命定格在那一天。"  


    (一)线程

    (1)线程的概念

     一个程序的执行路线上,叫做线程。

    更准确的定义是:线程无非是"一个进程内部的控制序列".

    ①一个进程至少有一个执行流(线程);

    ②线程本质上是在进程内部运行的,享用同一块进程地址空间(这里暂且这样理解);

    ③线程的资源(进程地址空间),本质上是经由进程进行合理分配。


    (2)线程的特点 

    优点:

    ①创建一个线程,肯定要比创建一个进程损耗的代价要小。

    ②线程存在调度切换,但比进程间切换做的工作要小。

    ③线程占用的资源更少。

    ④可以充分利用处理器进行“并行”处理......

     

    缺点:

    ①性能损失:太多的线程,对于有限处理器进行来回切换,可能会造成较大性能损失。

    ②健壮性降低:引发 线程安全问题。

    ③缺乏访问控制;编写与调试一个多线程程序比单线程程序困难得多  .......        

     

    线程异常;

    一旦分支线程出现异常,触发信号,进而整个进程也会崩溃。        

    线程资源;

    文件描述符、每个信号的处理方法、用户id和组id

    线程虽然共享资源,但也拥有一部分自己私有的部分。

    线程id 、独立的栈、寄存器.......

    适用场所;

    以计算加密为主的;

    IO密集型:刷新磁盘 访问数据库......


    (3)Linux中的进程与线程

    这里就要更新一下,之前对进程概念的解释。

    它不浅显地认为,是一个运行起来的程序。也不是创建PCB,链接入调度队列,建立进程地址空间,建立页表与映射关系.....

    站在系统层面上;

    进程是资源分配基本实体(单位)        

    线程是调度的基本单位

    CPU是怎样识别出进程和线程的?

    不能!但根本不用识别!因为进程不是由一个一个task_struct标识的。CPU眼中只有执行流。

    因此,在认知层面上,也叫做轻量级进程。       

    如何理解linux下不存在多线程?

    当线程足够多的时候,操作系统需要管理线程!(先描述,再组织)......必然需要再搭建一套,和进程类似的控制块!因此,为了简化设计,所以复用了进程管理的逻辑,进行线程管理。

     

    (4)浅谈页表与内存

     

    一般在32位系统下的,用的是二级页表。64位机器则用的是多级页表。        

    通过分隔比特位,去查寻每个页表的位置。

    主要是由集成 在CPU内部的 MMU单元硬件完成映射! (软硬件结合)


     

    (二)线程库

    我们知道,Linux并没有真正意义的线程,所以也没有提供真正意义上与线程有关的系统调用接口!

    但也提供了,原生线程库的方案。

    (1)POSIX线程库:

    注意:linux不提供线程库,所以编译的时候带上  -lpthread

    ①线程创建

     #include

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

    void *(*start_routine) (void *), void *arg);

    thread:返回线程ID

    attr:线程属性,一般设置NULL(默认)

    start_routine:函数指针,线程启动时执行的函数

    arg:传给启动函数的参数

     

    ②线程等待

    同进程等待同理,也需要知道,完成的任务的程度。

    #include

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

    thread:线程ID

    retavl:执行结果(类似退出码)

     

     

    ③线程终止

    这里只讨论,线程正常终止! 

    #include

    void pthread_exit(void *retval);

    return xxx; 

     

    #include

    int pthread_cancel(pthread_t thread);

     


    (2)线程运行

    我们分别用创建的三个线程,打印一句话。

     

    ①如何理解线程(pthread_t)id 与 pid?

     我们通过获取进程 的pid ppid; 

    如果要获取 线程的id,库里提供了一个函数 

    #include

    pthread_t pthread_self(void);

    1. //查看线程 lwp
    2. ps -aL

     但线程id 看起来更像是地址; 

     

     

     因此,由pthread库提供的 线程id 实质上就是进程地址空间上 mmap区域的地址。

     内核区别线程 在于 LWP

     而用户区(提供接口) 线程id    

    ②如何理解线程可以不被join?

    如果不关心线程的返回值

    join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

    #include

    int pthread_detach(pthread_t thread);

      

     

    ③如何理解pthread_cancel?

     ​​​​​

     对于pthread_cancel而言,很少用从来去 取消它 主线程。一般都会去用作 处理一个进程中的分支线程


    总结:

    ①进程与线程的概念区别。

    ②线程的优缺点,以及适用场所

    ③POSIX库 提供的线程函数。


    本篇就到这里结束了,感谢你的阅读!

    祝你好运~ 

     

  • 相关阅读:
    shiroFilter配置详解
    32 | 未来之路:HTTP/3展望
    安科瑞带防逆流功能的数据通讯网关-安科瑞黄安南
    一文读懂:低代码和无代码的演进历程、应用范围
    了解CSS中的link和@import引入CSS的区别
    TypeScript报错:Object is possibly “null“ 解决方法——断言函数
    微信小程序-生成canvas图片并保存到手机相册
    如何使用WinDbg查找蓝屏原因
    CSS3 就可以写出一个苹果官方渐变颜色文字效果,真的太逼真了!
    34. 在排序数组中查找元素的第一个和最后一个位置
  • 原文地址:https://blog.csdn.net/RNGWGzZs/article/details/126215660