6.3 设置线程属性
存在一些可用来确定线程上下文的关于线程的信息。这些信息用于重建线程的环境。令对等线程相互之间产生区别的是id、定义线程状态的寄存器组、优先级和它的栈。这些属性使得线程有了自己的身份。
POSIX线程库定义了线程属性对象(attribute object),它封装了线程属性的一个子集。这些属性可以被线程的创建者访问和更改。下面是可以被更改的线程属性:
竞争范围
栈大小
栈地址
分离的状态
优先级
调度策略和参数
线程属性对象可以同一个或多个线程关联。属性对象是定义了一个或一组线程的行为的概要(profile)。一旦对象被创建并初始化,可以在对线程创建函数的调用中重复引用它。如果重复使用,便会创建一组有着相同属性的线程。所有使用该属性对象的线程继承所有的属性值。一旦使用线程属性对象创建了线程,多数属性就不能够在线程使用中被改动。
范围属性描述了哪些线程同特定线程竞争资源。线程在两个竞争范围内争夺资源:
进程范围
系统范围
线程依照竞争范围和分配域(它被指派到的处理器集)来同其他线程竞争处理器的使用。有着进程竞争范围的线程同进程中其他线程竞争,而有着系统竞争范围的线程同系统分配的其他进程的线程竞争资源。有着系统范围的线程和系统中所有线程一起被排序和调度。
线程的栈大小和位置是在线程被创建时设置的。如果线程栈的大小和位置没有在创建期间指定,则系统会赋给它默认的大小和位置。默认大小同系统相关,是由进程所允许的线程最大数目、进程地址空间的指定大小、系统资源使用的空间等决定的。线程的栈大小必须足够大,以满足任何函数调用、线程调用的进程外部代码(如库代码)、局部变量存储的需要。有着多个线程的进程应当有足以满足其所有线程栈的栈段。分配给进程的地址空间限制了栈的大小,从而限制了每个线程栈的大小。线程栈地址对于访问有着不同属性的内存区域的应用程序,可能会很重要。当您指定栈的位置时,需要注意的是,线程要求多少空间以及确保该位置不会同其他对等线程的栈发生重叠。
分离的线程是那些已经从它们的创建者中分离出来的线程。它们在终止或退出时,不需要同其他对等线程或主线程进行同步。它们仍共享所属进程的地址空间,但是由于它们是分离的,创建它们的进程或线程不能够对它们进行控制。当线程终止时,线程的id和状态由系统保存。在默认情况下,一旦线程终止,该情况会通知给创建者,线程的id和状态会返回给创建者。如果线程是分离的,则不会使用资源来保存状态或线程id。这些资源立即可以被系统重用。如果线程的创建者不需要在继续处理之前等待线程终止,或者如果线程不要求在终止时同其他对等线程进行任何类型的同步,那么该线程可以成为一个分离的线程。
线程从进程继承调度策略。线程有优先级,而且优先级最高的线程会在较低优先级的线程之前执行。通过对线程区分优先次序,系统中需要立即执行或响应的任务会被指定到处理器上并得到时间片。如果有着更高优先级的线程可以运行,则正在执行的线程会被抢占。线程的优先级可以被降低或提高。调度策略也决定了哪个线程会被指派到处理器上。可使用的策略有先进先出(FIFO)、轮询(RR)等。通常,没有必要在进程执行期间改变线程的调度属性。如果进程环境发生变动,改变了时间约束,使得您需要改进进程的性能,则可能需要对调度进行改动。但是要考虑到改动应用程序中指定进程的调度属性,可能会对应用程序的总体性能产生负面影响。