• [17]APUE:线程


    通常情况下,线程模型的并发性能优于进程模型,但不总是这样

    线程的优势:

    1. 线程的创建、销毁及上下文切换代价比进程低
    2. 某些情况下,使用线程可以简化逻辑,避免异步编程的复杂性
    3. 同一进程内所有线程共享全局内存段,没有进程间通信的开销

    线程的劣势:

    1. 线程之间协作的顺序(时序)是完全随机的,*nix 内核的实现中也不包括对线程时序的完全控制,线程的不可控特性可能会带来某些测试过程中难以复现的 BUG,业务风险较高
    2. 线程之间的数据共享,同时也带来了数据竞争的问题,需要十分谨慎地的处理临界区数据

     *nix 平台下的线程实现

    1. 在内核层面的实现中,线程本质上还是进程模型,用户空间看到的每一线程,都对应于内核中一个进程(lwp:light weight process),用户空间的进程 ID,对应于内核层面的进程组 ID
    2. 线程的并发性能提升并非线性增长,各种锁机制的存在,都会造成线程并发性能的降低
    3. 多线程编程需要对特定硬件平台的特性有更深入的了解,否则容易陷入“伪共享”等硬件相关的性能瓶颈中

    线程的创建与终止

    #include <pthread.h>
    //pthread_* 类的函数成功返回 0;出错时,直接返回错误码,同时也会设置 errno
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
    void pthread_exit(void *retval);
    pthread_t pthread_self(void);
    • pthread_self 函数用于线程取得自身的线程 ID
      • 此处的 ID 是用户空间的概念,只在线程所属的进程环境下有意义,通常情况下就是一个指向特定结构体的内存地址(Linux/FreeBSD)
      • 操作系统范围内可以重复,同一进程中的线程退出后,其 ID 也可以立即被复用
    • 线程执行函数中调用 return 也可以终止自身

    释放线程所占用的资源

    #include <pthread.h>
    int pthread_detach(pthread_t thread);
    int pthread_join(pthread_t thread, void **retval);
    • 调用 pthread_detach(pthread_self()) 可使线程自身处于 detach 处态,线程退出后,其占用的资源将自动释放
    • 同一进程环境中的其它线程可以使用 pthread_join 函数获得指定线程的退出状态,同时释放其所占用的资源

    线程属性设置

    #include <pthread.h>
    int pthread_attr_init(pthread_attr_t *attr);
    int pthread_attr_destroy(pthread_attr_t *attr);
    
    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
    • 线程属性设置使用 pthread_attr_t 数据类型,必须首先调用 pthread_attr_init 初始化之后才能使用,使用完成之后需要调用 pthread_attr_destroy 释放资源
    • pthread_attr_setdetachstate 函数中 detachstate 参数的可选值有:PTHREAD_CREATE_JOINABLE、PTHREAD_CREATE_DETACHED,默认是前者,效果与线程自身调用 pthread_detach(pthread_self()) 相同

    线程 ID 比较

    int pthread_equal(pthread_t t1, pthread_t t2); 
    • 不同操作系统中的线程实现方式存在差异,不能直接用 '==' 判断

    线程清理函数

    #include <pthread.h>
    void pthread_cleanup_push(void (*cleanup_routine)(void *), void *arg);
    void pthread_cleanup_pop(int execute);
    • 不同的操作系统中,pthread_cleanup_push 与 pthread_cleanup_pop 可以实现为宏或函数,使用时必须一一配对使用,执行顺序与设置顺序相反,与进程清理中的 atexit 函数类似
    • pthread_cleanup_pop 的参数为 0 时,将不执行对应的清理行为
    • 在实现为宏的平台上(如:FreeBSD、MAX OS),函数退出必须调用 pthread_exit,而不能使用 return 返回,否则清理动作将得不到执行
  • 相关阅读:
    python---基础部分
    自动化测试---Selenium IDE安装及操作
    自动化测试---Selenium IDE概念
    自动化测试----概念
    jmeter---后端监听器
    jmeter---分布式测试
    jmeter---runtime控制器
    什么是 MyBatis 的接口绑定,有什么好处?
    接口绑定有几种实现方式,分别是怎么实现的?
    Apache Shiro 的三大核心组件
  • 原文地址:https://www.cnblogs.com/hadex/p/6128438.html
Copyright © 2020-2023  润新知