zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/lienhua34/p/4086184.html
Copyright © 2011-2022 走看看