• 线程属性API


    数据类型:pthread_attr_t

    操作API:

    // 初始化线程属性
    int pthread_attr_init(pthread_attr_t *attr);// 初始化为系统支持的所有属性的默认值
    -------------------------------------------------------------------------------------
    // 销毁线程属性
    int pthread_attr_destroy(pthread_attr_t *attr);// 回收初始化时给此属性分配的资源

     1:分离属性

      描述:分离线程终止时由系统回收线程资源,而一般线程需要pthread_join(pthread_t)函数来回收资源

    // 设置分离线程属性
    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
        detachstate可取两个值:
                            1:默认是PTHREAD_CREATE_JOINABLE,不特意设置线程属性时默认是它
                            2:PTHREAD_CREATE_DETACHED(线程分离)
    -------------------------------------------------------------------------------------
    // 获得分离属性
    int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
    例:设置分离属性的线程
        int makedetachpthread(void *(*fn)(void *), void *arg)
        {
            int             err;
            pthread_t         tid;
            pthread_attr_t  attr;
            err = pthread_attr_init(&attr);
            if(err != 0){
                return err;
            }
            err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            if(err == 0)
                pthread_create(&tid, &attr, fn, arg);
            pthread_attr_destroy(&attr);// 这里对destroy的返回值没有检查,默认是能够正确回收attr的资源
            return err;
        }

    2:堆栈大小及起始地址属性

      描述:线程的堆栈是使用的进程的堆栈,进程的堆栈是有限的,所以在某些嵌入式程序中会合理设置线程堆栈大小

    // 设置线程堆栈大小
    /* 
       如果堆栈空间不足,pthread_create将返回err=12,在<limits.h>中定义#define ENOMEM 12 // Out of memory 
    设置的栈区大小不能小于PTHREAD_STACK_MIN
    */
    int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
    // 获得当前线程堆栈大小
    int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
    -------------------------------------------------------------------------------------
    // 设置线程堆栈大小及自定义堆栈空间
    /*
        如上所说,进程的堆栈空间是有限的,如果此时堆栈空间已经使用完,而你还想继续创建线程,那么此线程只能放在别处
    下面的函数比pthread_attr_setstacksize多了一个stackaddr参数,用于指定放置线程的起始地址(通常是用malloc分配堆
    上空间来使用).
    */
    int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
    // 获取线程堆栈的起始地址和堆栈大小
    int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);

    3:堆栈警戒区属性

      描述:警戒区的意义在于,允许线程在超出线程栈后还能操作一段栈空间(会有警告消息发送给它),

    // 设置线程栈警戒区
    /*
        警戒区默认大小是一页字节guardsize设置为0表示不提供警戒区机制,注意的是:当使用pthread_attr_setstack改变了stackaddr参数后,系统默认应用
    程序自己管理警戒区,类似将guardsize设置为0.
    */
    int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
    // 获取线程警戒区大小
    int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);

     注:下面的两个线程属性是不包含在pthread_attr_t数据结构中的,分别是取消状态取消类型

      可知这两个属性是回应pthread_cancel函数的,pthread_cancel函数只是对某个同一线程中的某个线程发出取消请求(好比目标线程调用pthread_exit(PTHREAD_CANCELED)),至于目标线程如何处理这个请求,就是这两个属性来定义的.

    1:取消状态属性

    // 设置取消状态
    int pthread_setcancelstate(int state, int *oldstate)
        state取值:
            PTHREAD_CANCEL_ENABLE:  默认值,表示接受其他线程pthread_cancel取消信号
            PTHREAD_CANCEL_DISABLE: 阻塞线程pthread_cancel取消信号,当状态改为PTHREAD_CANCEL_ENABLE时再依次处理请求

      既然本线程收到了取消的请求,那么我什么时候执行取消动作呢?这就引出了取消点的概念,线程会在取消点处处理取消请求(处理方式就是调用pthread_exit(PTHREAD_CANCELED)),取消点可能会出现在下列函数中:

                                 

      也可以自己设置取消点的位置:

    // 手动设置取消点的位置
    void pthread_testcancel(void);

      当然,设置取消点要生效还是得取消状态值是:PTHREAD_CANCEL_ENABLE的情况下.

    2:取消类型属性

      前面所讲,获得取消请求之后线程要到取消点才执行取消动作,这其实是一种取消类型属性,叫做延迟取消(deferred cancel)类型,还有一种叫异步取消类型,这种类型就不需要等到取消点才执行取消动作,线程可以在任意时间取消.

    // 设置取消类型
    int pthread_setcanceltype(int type, int *oldtype)
        type取值:
            PTHREAD_CANCEL_DEFERRED:  默认值,延迟到取消点才执行取消动作
            PTHREAD_CANCEL_ASYNCHRONOUS: 随时会执行取消动作
  • 相关阅读:
    sqlserver,获取调用存储过程返回数据的方法。
    手动为弹窗添加一个阴影背景。
    bootstrap资料链接
    进入Linux救援(rescue)模式的四大法门
    virtual box 5.2.12 扩展包安装
    pypi配置国内开源镜像
    vs2015利用python加载dll调试配置
    ubuntu18安装ubuntu kylin软件中心
    firefox快捷键窗口和标签类
    设置双网卡路由
  • 原文地址:https://www.cnblogs.com/Flychown/p/7412494.html
Copyright © 2020-2023  润新知