Solaris2.4 多线程编程指南2--用多线程编程
时,就需要上G的空间。
堆栈的上限是很显然的,但下限呢?一定要有足够的堆栈空间来保存堆栈 框架和本地变量。
你可以用thr_min_stack()函数来获得绝对的最小堆栈容量,它返回运行一 个空过程所需要的堆栈空间。有实际用途的线程需要的更多,所以在减小线程 堆栈的时候要小心。
你通过两种方式指定一个堆栈。第一种是给堆栈地址赋空值,由实时的运 行库来为堆栈分配空间,但需要给stack_size参数提供一个期望的值。
另外一种方式是全面了解堆栈管理,为thr_create函数提供一个堆栈的指 针。这意味着你不但要负责为堆栈分配空间,你还要考虑在线程结束后释放这 些空间。
在你为自己的堆栈分配空间之后,一定要调用一个mprotect(2)函数来为它 附加一个红区。
Start_routine--指定新线程首先要执行的过程。当start_routine返回时, 线程用该返回值作为退出码退出(参考thr_exit(3T))。
注意,你只能指定一个参数。如果你想要多参数,把他们作成一个(例如 写入一个结构)。这个参数可以是任何一个由void说明的数据,典型的是一个 4字节的值。任何更大的值都需要用指针来间接传送。
Flags--指定创建线程的属性。在多数情况下提供0即可。
Flags的值通过位或操作来赋。
THR_SUSPENDED--新线程挂起,在thr_continue()后再执行 start_routine。用这种办法在运行线程之前对它进行操作(例如改变 优先级)。分离线程的终止被忽略。
THR_DETACHED--将新线程分离,使线程一旦终止,其资源可以得到立刻 回收利用。如果你不需要等待线程结束,设置此标志。 如果没有明确的同步要求,一个不挂起的,分离的线程可以在它 的创建者调用的thr_create函数返回之前终止并将线程号和其他资源 移交给其他线程使用。
THR_BOUND--将一个新线程永久绑定在一个LWP上(新线程为绑定线程)。
THR_NEW_LWP--给非绑定线程的同时性等级加1。效果类似于用 thr_setconcurrency(3T)来增加同时性等级,但是使用 thr_setconcurrency()不影响等级设置。典型的,THR_NEW_LWP在LWP池 内增加一个LWP来运行非绑定线程。
如果你同时指定了THR_BOUND和THR_NEW_LWP,两个LWP被创建,一 个被绑定在该线程上,另外一个来运行非绑定线程。
THR_DAEMON--标志新线程为守护线程。当所有的非守护线程退出后进程 结束。守护线程不影响进程退出状态,在统计退出的线程数时被忽略。 一个进程可以通过调用exit(2)或者在所有非守护线程调用 thr_exit(3T)函数终止的时候终止。一个应用程序,或它调用的一个库, 可以创建一个或多个在决定是否退出的时候被忽略的线程。用 THR_DAEMON标志创建的线程在进程退出的范畴不被考虑。 New_thread--在thr_create()成功返回后,保存指向存放新线程ID的地址。 调用者负责提供保存这个参数值指向的空间。 如果你对这个值不感兴趣,给它赋值0。 返回值--thr_thread在正常执行后返回0,其他值意味着错误。在以下情况 发生时,函数失败并返回相关值。
EAGAIN 超过系统限制,例如创建了太多的LWP。
ENOMEM 内存不够创建新线程。
EINVAL stack_base非空,但stack_size比thr_minstack()的返回值小。
2.1.11.3 Thr_create(3T)例程
例2-5显示了怎样用一个与创建者(orig_mask)不同的新的信号掩模来创建新线程。
在这个例子当中,new_mask被设置为屏蔽SIGINT以外的任何信号。然后创建者的信号掩模被改变,以便新线程继承一个不同的掩模,在thr_create()返回后,创建者的掩模被恢复为原来的样子。
例子假设SIGINT不被创建者屏蔽。如果最初是屏蔽的,用相应的操作去掉屏蔽。另外一种办法是用新线程的start routine来设置它自己的信号掩模。
Code Example 2-5 thr_create() Creates Thread With New Signal Mask
thread_t tid;
sigset_t new_mask, orig_mask;
int error;
(void)sigfillset(&new_mask);
(void)sigdelset(&new_mask, SIGINT);
(void)thr_sigsetmask(SIGSETMASK, &new_mask, &orig_mask):
error = thr_create(NULL, 0, dofunc, NULL, 0, &tid);
(void)thr_sigsetmask(SIGSETMASK, NULL, &orig_mask);
2.1.12获得最小堆栈
thr_min_stack(3T) 用thr_min_stack(3T)来获得线程的堆栈下限
#include
size_t thr_min_stack(void);
thr_min_stack()返回执行一个空线程所需要的堆栈大小(空线程是一个创 建出来执行一个空过程的线程)。
如果一个线程执行的不仅仅是空过程,应当给它分配比thr_min_stack()返 回值更多的空间。
如果线程创建时由用户指定了堆栈,用户应当为该线程保留足够的空间。在 一个动态连接的环境里,确切知道线程所需要的最小堆栈是非常困难的。
大多数情况下,用户不应当自己指定堆栈。用户指定的堆栈仅仅用来支持那 些希望控制它们的执行环境的应用程序。
一般的,用户应当让线程库来处理堆栈的分配。线程库提供的缺省堆栈足够 运行任何线程。
2.1.13设置线程的同时性等级
2.1.13.1 thr_getconcurrency(3T)
用thr_getconcurrency()来获得期望的同时性等级的当前值。实际上同时活动的线程数可能会比这个数多或少。
#include
int thr_getconcurrency(void)
返回值--thr_getconcurrency()为期望的同时性等级返回当前值。
2.1.13.2 Thr_setconcurrency(3T)
用thr_setconcurrency()设置期望的同时性等级。
#include
int thr_setconcurrency(new_level)
进程中的非绑定线程可能需要同时活动。为了保留系统资源,线程系统的缺 省状态保证有足够的活动线程来运行一个进程,防止进程因为缺少同时性而死锁。
因为这也许不会创建最有效的同时性等级,thr_setconcurrency()允许应用 程序用new_level给系统一些提示,来得到需要的同时性等级。
实际的同时活动的线程数可能比new_level多或少。
注意,如果没有用thr_setconcurrency调整执行资源,有多个 compute-bound(????)线程的应用程序将不能分配所有的可运行线程。
你也可以通过在调用thr_create()时设置THR_NEW_LWP标志来获得期望的同时性等级。
返回值--thr_setconcurrency()在正常执行后返回0,其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
EAGAIN 指定的同时性等级超出了系统资源的上限。
EINVAL new_level的值为负。
2.1.14得到或设定线程的优先级
一个非绑定线程在调度时,系统仅仅考虑进程内的其他线程的简单的优先级,
堆栈的上限是很显然的,但下限呢?一定要有足够的堆栈空间来保存堆栈 框架和本地变量。
你可以用thr_min_stack()函数来获得绝对的最小堆栈容量,它返回运行一 个空过程所需要的堆栈空间。有实际用途的线程需要的更多,所以在减小线程 堆栈的时候要小心。
你通过两种方式指定一个堆栈。第一种是给堆栈地址赋空值,由实时的运 行库来为堆栈分配空间,但需要给stack_size参数提供一个期望的值。
另外一种方式是全面了解堆栈管理,为thr_create函数提供一个堆栈的指 针。这意味着你不但要负责为堆栈分配空间,你还要考虑在线程结束后释放这 些空间。
在你为自己的堆栈分配空间之后,一定要调用一个mprotect(2)函数来为它 附加一个红区。
Start_routine--指定新线程首先要执行的过程。当start_routine返回时, 线程用该返回值作为退出码退出(参考thr_exit(3T))。
注意,你只能指定一个参数。如果你想要多参数,把他们作成一个(例如 写入一个结构)。这个参数可以是任何一个由void说明的数据,典型的是一个 4字节的值。任何更大的值都需要用指针来间接传送。
Flags--指定创建线程的属性。在多数情况下提供0即可。
Flags的值通过位或操作来赋。
THR_SUSPENDED--新线程挂起,在thr_continue()后再执行 start_routine。用这种办法在运行线程之前对它进行操作(例如改变 优先级)。分离线程的终止被忽略。
THR_DETACHED--将新线程分离,使线程一旦终止,其资源可以得到立刻 回收利用。如果你不需要等待线程结束,设置此标志。 如果没有明确的同步要求,一个不挂起的,分离的线程可以在它 的创建者调用的thr_create函数返回之前终止并将线程号和其他资源 移交给其他线程使用。
THR_BOUND--将一个新线程永久绑定在一个LWP上(新线程为绑定线程)。
THR_NEW_LWP--给非绑定线程的同时性等级加1。效果类似于用 thr_setconcurrency(3T)来增加同时性等级,但是使用 thr_setconcurrency()不影响等级设置。典型的,THR_NEW_LWP在LWP池 内增加一个LWP来运行非绑定线程。
如果你同时指定了THR_BOUND和THR_NEW_LWP,两个LWP被创建,一 个被绑定在该线程上,另外一个来运行非绑定线程。
THR_DAEMON--标志新线程为守护线程。当所有的非守护线程退出后进程 结束。守护线程不影响进程退出状态,在统计退出的线程数时被忽略。 一个进程可以通过调用exit(2)或者在所有非守护线程调用 thr_exit(3T)函数终止的时候终止。一个应用程序,或它调用的一个库, 可以创建一个或多个在决定是否退出的时候被忽略的线程。用 THR_DAEMON标志创建的线程在进程退出的范畴不被考虑。 New_thread--在thr_create()成功返回后,保存指向存放新线程ID的地址。 调用者负责提供保存这个参数值指向的空间。 如果你对这个值不感兴趣,给它赋值0。 返回值--thr_thread在正常执行后返回0,其他值意味着错误。在以下情况 发生时,函数失败并返回相关值。
EAGAIN 超过系统限制,例如创建了太多的LWP。
ENOMEM 内存不够创建新线程。
EINVAL stack_base非空,但stack_size比thr_minstack()的返回值小。
2.1.11.3 Thr_create(3T)例程
例2-5显示了怎样用一个与创建者(orig_mask)不同的新的信号掩模来创建新线程。
在这个例子当中,new_mask被设置为屏蔽SIGINT以外的任何信号。然后创建者的信号掩模被改变,以便新线程继承一个不同的掩模,在thr_create()返回后,创建者的掩模被恢复为原来的样子。
例子假设SIGINT不被创建者屏蔽。如果最初是屏蔽的,用相应的操作去掉屏蔽。另外一种办法是用新线程的start routine来设置它自己的信号掩模。
Code Example 2-5 thr_create() Creates Thread With New Signal Mask
thread_t tid;
sigset_t new_mask, orig_mask;
int error;
(void)sigfillset(&new_mask);
(void)sigdelset(&new_mask, SIGINT);
(void)thr_sigsetmask(SIGSETMASK, &new_mask, &orig_mask):
error = thr_create(NULL, 0, dofunc, NULL, 0, &tid);
(void)thr_sigsetmask(SIGSETMASK, NULL, &orig_mask);
2.1.12获得最小堆栈
thr_min_stack(3T) 用thr_min_stack(3T)来获得线程的堆栈下限
#include
size_t thr_min_stack(void);
thr_min_stack()返回执行一个空线程所需要的堆栈大小(空线程是一个创 建出来执行一个空过程的线程)。
如果一个线程执行的不仅仅是空过程,应当给它分配比thr_min_stack()返 回值更多的空间。
如果线程创建时由用户指定了堆栈,用户应当为该线程保留足够的空间。在 一个动态连接的环境里,确切知道线程所需要的最小堆栈是非常困难的。
大多数情况下,用户不应当自己指定堆栈。用户指定的堆栈仅仅用来支持那 些希望控制它们的执行环境的应用程序。
一般的,用户应当让线程库来处理堆栈的分配。线程库提供的缺省堆栈足够 运行任何线程。
2.1.13设置线程的同时性等级
2.1.13.1 thr_getconcurrency(3T)
用thr_getconcurrency()来获得期望的同时性等级的当前值。实际上同时活动的线程数可能会比这个数多或少。
#include
int thr_getconcurrency(void)
返回值--thr_getconcurrency()为期望的同时性等级返回当前值。
2.1.13.2 Thr_setconcurrency(3T)
用thr_setconcurrency()设置期望的同时性等级。
#include
int thr_setconcurrency(new_level)
进程中的非绑定线程可能需要同时活动。为了保留系统资源,线程系统的缺 省状态保证有足够的活动线程来运行一个进程,防止进程因为缺少同时性而死锁。
因为这也许不会创建最有效的同时性等级,thr_setconcurrency()允许应用 程序用new_level给系统一些提示,来得到需要的同时性等级。
实际的同时活动的线程数可能比new_level多或少。
注意,如果没有用thr_setconcurrency调整执行资源,有多个 compute-bound(????)线程的应用程序将不能分配所有的可运行线程。
你也可以通过在调用thr_create()时设置THR_NEW_LWP标志来获得期望的同时性等级。
返回值--thr_setconcurrency()在正常执行后返回0,其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
EAGAIN 指定的同时性等级超出了系统资源的上限。
EINVAL new_level的值为负。
2.1.14得到或设定线程的优先级
一个非绑定线程在调度时,系统仅仅考虑进程内的其他线程的简单的优先级,

