• UNIX环境编程学习笔记(27)——多线程编程(二):控制线程属性


    lienhua34
    2014-11-09

    1 线程属性概括

    POSIX 线程的主要属性包括 scope 属性、detach 属性、堆栈地址、堆栈大小、优先级。在头文件 pthread.h 中定义了结构体pthread_attr_t 来记录线程的属性。

    在创建线程的函数pthread_create 的第二个参数 attr 就是一个pthread_attr_t结构体的指针,通过该参数,我们可以控制新创建的线程的属性。如果 atrr参数为 NULL,表示创建一个默认属性的新线程。

    pthread_attr_t 结构体对于应用程序来说是透明的,也就是说应用程序不需要关心各个属性在该结构体中的实现字段。头文件 pthread.h 提供了操作这些属性的函数。pthread_attr_init 函数和pthread_attr_destroy函数分别用于线程属性pthread_attr_t 结构体的初始化和摧毁。

    #include <pthread.h>

    int pthread_attr_init(pthread_attr_t *attr);

    int pthread_attr_destroy(pthread_attr_t *attr);

    返回值:若成功则返回0,否则返回错误编号

    在调用pthread_create 函数之前,调用pthread_attr_init 函数初始化pthread_attr_t 结构体为操作系统支持的线程所有属性默认值。在调用pthread_create 函数创建线程之后,要调用pthread_attr_destroy 函数来摧毁pthread_attr_t 结构体,因为某些线程属性对象可能分配了动态内存空间。

    下面简单说明一下几个主要的线程属性及其操作函数。

    1.1 detach 属性

    detach属性,也称为分离状态,表示新线程是否与进程中其它线程脱离同步。如果设置为PTHREAD_CREATE_DETACHED, 此时新线程将以分离状态启动, 且新线程在退出时自行释放所占用的资源。如果设置为PTHREAD_CREATE_JOINABLE,新线程在退出后,需要调用pthread_join来获取该线程的退出状态,并释放该线程所占有的资源。缺省值为PTHREAD_CREATE_JOINABLE。该属性的操作函数为,详细说明请参考http://pubs.opengroup.org

    #include <pthread.h>

    int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);

    int pthread_attr_setdetachstate(pthread_attr_t *restrict attr, int detachstate);

    两个函数返回值:若成功则返回0,否则返回错误编号

    1.2 调度策略属性

    新线程的调度策略包括SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和SCHED_FIFO(实时、先入先出),缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。调度策略属性的操作函数为,详细说明请参考http://pubs.opengroup.org

    #include <pthread.h>

    int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

    int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

    1.3 优先级属性

    该属性在实现时通过 struct sched_param 结构中的sched_priority 整型变量来表示。这个属性仅当调度策略为实时(即SCHED_RR 或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam() 函数来改变,缺省为 0. 系统支持的最大和最小的优先级值可以用函数sched_get_priority_max和sched_get_priority_min 得到。详细说明请参考http://pubs.opengroup.org

    #include <pthread.h>

    int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);

    int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

    1.4 scope 属性

    scope 属性表示线程间竞争 CPU 的范围,也就是说线程优先级的有效范围。其有效值有两个: PTHREAD_SCOPE_SYSTEM 和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争 CPU 时间,后者表示仅与同进程中的线程竞争 CPU 时间。详细说明请参考http://pubs.opengroup.org

    #include <pthread.h>

    int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);

    int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);

    2 线程分离状态例子

    要创建一个分离状态的新线程,我们调用pthread_attr_setdetachstate函数来设置pthread_create 函数的 attr 参数的 detachstate 属性为PTHREAD_CREATE_DETACHED,或者在创建线程之后,调用pthread_detach 函数来设置一个线程为分离状态。pthread_detach 函数的声明如下,

    #include <pthread.h>

    int pthread_detach(pthread_t tid);

    返回值:若成功则返回0,否则返回错误编号

    如果线程处于分离状态,则线程的底层存储资源在线程终止时立即被收回。对于处于分离状态的线程,调用pthread_join 函数会返回错误。下面我们来看一个分离状态的例子,

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <pthread.h>
    
    void *
    my_thread(void *arg)
    {
      printf("in new thread. 
    ");
      sleep(1);
      printf("out new thread.
    ");
      return ((void *)0);
    }
    
    int
    main(void)
    {
      int err;
      pthread_t tid;
      void *tret;
      pthread_attr_t  attr;
    
      err = pthread_attr_init(&attr);
      if (err != 0) {
        printf("pthread_attr init error: %s
    ", strerror(err));
        exit(-1);
      }
      
      err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      if (err != 0) {
        printf("pthread_attr_setdetachstate error: %s
    ", strerror(err));
        exit(-1);
      }
      
      
      err = pthread_create(&tid,  &attr, my_thread, NULL);
      if ( err != 0) {
        printf("can't create thread: %s
    ", strerror(err));
        exit(-1);
      }
      err = pthread_join(tid, &tret);
      if (err != 0) {
        printf("pthread_join error: %s
    ", strerror(err));
        exit(-1);
      }
      printf("new thread return value: %d
    ", (int)tret);
      pthread_attr_destroy(&attr);
      
      exit(0);
    }

    上面的程序中,设置了调用pthread_attr_setdetachstate 函数将传递给pthread_create 函数的 attr 参数的 detachstate 属性设置为PTHREAD_CREATE_DETACHED。则pthread_create 函数将以分离状态创建新线程, 然后对新线程调用pthread_join 函数。编译该程序,生成并执行可执行文件pthread_detach_demo,

    lienhua34:demo$ gcc -o pthread_detach_demo -pthread pthread_detach_demo.c
    lienhua34:demo$ ./pthread_detach_demo
    in new thread.
    pthread_join error: Invalid argument

    从上面的运行结果,我们可以看到对于分离状态的线程,调用pthread_join函数时报错了。如果将上面程序中调用pthread_attr_setdetachstate 的一行代码注释掉,然后重现编译该程序,生成并执行可执行文件pthread_detach_demo,

    lienhua34:demo$ gcc -o pthread_detach_demo -pthread pthread_detach_demo.c
    lienhua34:demo$ ./pthread_detach_demo
    in new thread.
    out new thread.
    new thread return value: 0

    从上面运行结果可以看到,对于非分离状态的线程,pthread_join 函数能够正常获取该线程的返回值。

    (done)

  • 相关阅读:
    利用DllPlugin性能优化
    Shimming 的作用
    用webpackPrefetch:true提升性能
    webpack打包分析学习笔记
    分块打包学习笔记
    tree shaking学习笔记
    Map与实体类相互转换
    项目可以run但不能debug
    jeecg-boot框架默认create_time Desc去掉
    List<实体类>根据多个字段去重
  • 原文地址:https://www.cnblogs.com/lienhua34/p/4086184.html
Copyright © 2020-2023  润新知