网络编程学习总结4

线程管理

一、基本概念

    1、线程是进程的执行路线,它是进程内部的控制序列,或者说线程是进程的一部分(进程是一个资源单位,线程是执行单位,线程是进程的一部分,负责真正的执行)

    2、线程是轻量级的,没有自己独立的代码段、数据段、bss段、堆、环境变量、命令行参数、文件描述符、信号处理函数、当前目录信息等资源

    3、线程有自己独立的栈内存、线程ID、错误码、信号屏蔽掩码

    4、一个进程中可以包含多个线程(多个执行路线),但是至少有一个线程在活动,称为主线程

    5、ps -T -p <pid> 查看pid进程中的线程情况 或者htop命令也可以查看  

    6、线程是进程的实体,可以当做系统独立的任务调度和分配的基本单位

    7、线程有不同的状态、属性,系统提供了线程的控制接口,例如:创建、销毁、控制

    8、进程中的所有线程同在一个虚拟地址空间中,进程中的所有资源对于线程而言都是共享的,因此当多个线程协同工作时需要解决资源竞争问题(加锁)

    9、线程的系统开销很小、任务切换快、多个线程之间不需要数据交换、因此不需要类似于XSI的通信机制,因此使用线程简单而高效

    10、线程之间有优先级的差异

二、POSIX线程

    1、早期的UNIX和Linux系统没有线程概念,微软的Windows系统首先使用的线程,之后UNIX和Linux系统也逐渐增加了线程

    2、早期各个厂商有自己都私有的线程库,而且接口的实现差异较大,不利于移植,世界标准化组织于1995年,制定了统一的线程接口标准规范,遵循该标准的线程称为POSIX线程,简称pthread

    3、pthread线程包含一个头文件 <pthread.h> 和一个共享库 libpthread.so

        -pthread

三、线程管理

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

    功能:创建新线程

    thread:输出型参数,用于获取线程ID

    attr: 用于设置线程属性,一般写NULL即可

    start_routine:线程的入口函数,相当于主线程的main函数

    arg:传递给start_routine入口函数的参数

    返回值:成功返回0,失败返回错误编码

    注意:入口函数的参数、返回值要确保它的可持续性,因此不太适合使用栈内存,可以考虑堆内存、全局变量

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

    功能:等待线程结束,并获取该线程结束时的入口函数的返回值,并释放线程资源

    thread:要等待的线程的ID

    retval:用于存储线程结束时返回值的地址,拿到返回值变量本身

    返回值:成功返回0,失败返回错误编码

    pthread_t pthread_self(void);

    功能:获取当前线程的线程ID

    int pthread_equal(pthread_t t1, pthread_t t2);

    功能:比较两个线程ID是否一致

    返回值:一致返回非零值,不一致返回0

    注意:在个别操作系统下,pthread_t 是以结构实现的,大部分是以 unsigned long 呈现,为了可移植性,不能直接使用 == 比较

        pthread_t tid;  //不要初始化 提高可移植性

四、线程的执行轨迹

    同步方式:默认(可结合状态)

        创建子线程后,主线程通过调用pthread_join函数等待子线程终止,并释放线程资源

    异步方式:(分离状态)

        无需创建者等待(如果创建者调用pthread_join函数会立即返回),线程结束时由系统释放资源

    原因:为了避免线程资源泄漏,每个可结合状态的线程必须显示地调用pthread_join来回收资源,或者将其变成分离状态

    int pthread_detach(pthread_t thread);

    功能:让已创建的thread标识的线程与创建者线程分离

   

    pthread_detach两种用法:

        1、主线程中调用 pthread_detach(tid)

        2、新线程中调用 pthread_detach(pthread_self())

        注意:无论哪种分离写法,都必须发生在pthread_join之前,否则join一旦进入等待,再分离也不会退出等待

五、线程的终止

    1、线程执行了入口函数的最后一行代码 包括return语句

    2、线程执行了pthread_exit函数

        void pthread_exit(void *retval);

        功能:结束当前线程

        retval:等同于return 后面的val

       

        注意:从表面上看当主线程结束后,子线程会跟着一起结束,就会误以为主线程的结束影响了子线程的结束,但是实际上子线程之所以结束是因为主线程执行了main函数中隐藏的return语句,导致了整个进程结束,所以进程中所有的线程才会随之结束。

        如果主线程调用pthread_exit自杀,这样就没有线程去执行main函数的return语句,进程就不会提前结束,子线程就不受影响了

        总结:主线程结束不会影响子线程的执行

    3、如果所在的进程结束,所有的线程都随之结束

    4、向指定线程发送取消请求

        int pthread_cancel(pthread_t thread);

        功能:向指定线程发送取消请求,默认情况下会响应请求

        int pthread_setcancelstate(int state,int *oldstate);

        功能:设置本线程是否响应取消请求,并获取之前的状态

            PTHREAD_CANCEL_ENABLE 允许响应

            PTHREAD_CANCEL_DISABLE 禁止响应

    int pthread_setcanceltype(int type, int *oldtype);

    功能:设置延迟响应

     PTHREAD_CANCEL_DEFERRED    延迟响应 在接收到取消请求后不立即响应,而是等待合适的时间再响应

     PTHREAD_CANCEL_ASYNCHRONOUS 立即响应

   

六、线程属性

    pthread_attr_t

    typedef struct

    {

       int  detachstate;     线程的分离状态

       int  schedpolicy;     线程调度策略

       struct sched_param schedparam;      线程的调度参数

       int  inheritsched;    线程的继承性

       int  scope;           线程的作用域

       size_t  guardsize;    线程栈末尾的警戒缓冲区大小

       int stackaddr_set;    线程栈的设置

       void * stackaddr;     线程栈的位置

       size_t   stacksize;   线程栈的大小

    }pthread_attr_t;

    在/usr/include/i386-linux-gnu/bits/pthreadtypes.h这个文件中找到关于pthread_attr_t的定义,但是该定义不是真的线程属性结构体的定义,真实的定义应该如上所示,大概是因为pthread不想让用户看到它对pthread_attr_t的实现,希望用户借助它提供的接口函数进行获取、设置属性



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值