Solaris2.4 多线程编程指南2--用多线程编程
2 用多线程编程
2.1线程(函数)库(The Threads Library)
用户级多线程是通过线程库,libthread来实现的(参考手册第3页: library routines)。线程库支持信号,为可运行的程序排队,并负责同 时操纵多任务。
这一章讨论libthread中的一些通用过程,首先接触基本操作,然后循 序渐进地进入更复杂的内容。
创建线程-基本特性 Thr_create(3T)
获得线程号 Thr_self(3T)
执行线程 Thr_yield(3T,the below is same)
挂起或继续线程 Thr_suspend
Thr_continue
向线程送信号 Thr_kill
设置线程的调用掩模 Thr_sigsetmask
终止线程 Thr-exit
等待线程终止 Thr-join
维护线程的私有数据 Thr_keycreate
Thr_setspecific
Thr_getspecific
创建线程-高级特性 Thr_create
获得最小堆栈容量 Thr_min_stack
获得或设置线程的同时性等级 Thr_getconcurrency
Thr_setconcurrency
获得或设置线程的优先级 Thr_getprio
Thr_setprio
2.1.1创建线程-基本篇
thr_create过程是线程库所有过程当中最复杂的一个。这部分的内容仅适用于你使用thr_create的缺省参数来创建进程。
对于thr_create更加复杂的使用,包括如何使用自定参数,我们将在高级特性部分给出说明。
thr_create(3T)
这个函数用于在当前进程中添加一个线程。注意,新的线程不继承未处理的信号,但继承优先级和信号掩模。
#include
int thr_create(void *stack_base,size_t stack_size,
void *(*start_routine) (void*),void *arg,long flags,
thread_t *new_thread);
size_t thr_min_stack(void);
stack_base--新线程的堆栈地址。如果stack_base是空则thr_create()按 照stack_size为新线程分配一个堆栈。
Stack_size--新线程堆栈的字节数。如果本项为0,将使用缺省值,一般 情况下最好将此项设为0。并不是每个线程都需要指定堆栈空间。线程库为每个线程的堆栈分配1M 的虚拟内存,不保留交换空间。(线程库用mmap(2)的MAP_NORESERVE的选项 来实现这种分配)。
Start_routine--指定线程开始执行的函数。如果start_routine返回, 线程将用该函数的返回值作为退出状态而退出。(参考thr_exit(3T))。
Flags--指定新线程的属性,一般设置为0。
Flags的值是通过下列内容的位同或来实现的(最后四个flags在高级特性中给出)。
1. THR_DETACHED 将新线程分离,使得它的线程号和其他资源在线程 结束时即可以回收利用。当你不想等待线程终止时,将其置位。如果没有明确的 同步需求阻碍,一个不挂起的,分离的线程可以在创建者的thr_create返回之前 终止并将其线程号分配给一个心得线程。
2. THR_SUSPENDED挂起新线程,直到被thr_continue唤醒。
3. THR_BOUND把新线程永久绑定在一个LWP上(生成一个绑定线程)。
4. THR_NEW_LWP将非绑定线程的同时性级别加1。
5. THR_DAEMON新线程为一个守护线程。
New_thread--指向存储新线程ID的地址。多数情况下设置为0。
Return Values--thr_create()在成功执行后返回0并退出。任何其他返回值表明有错误发生。当以下情况被检测到时,thr_create()失败并返回响应的值。
EAGAIN :超出了系统限制,例如创建了太多的LWP。
ENOMEM:可用内存不够创建新线程。
EINVAL:stack_base不是NULL而且stack_size比thr_minstack()函数返回的最小堆栈要小。
2.1.2获取线程号
thr_self(3T) 获得自身的线程号。
#include
thread_t thr_self(void)
返回值--调用者的线程号。
2.1.3放弃执行
thr_yield(3T)
thr_yield停止执行当前线程,将执行权限让给有相同或更高优先权的线程。
#include
void thr_yield(void);
2.1.4挂起或继续执行线程
thr_suspend(3T) 挂起线程。
#include
int thr_suspend(thread_t target_thread);
thr_suspend()立即挂起由target_thread指定的线程。在thr_suspend成功返回后,挂起的线程不再执行。后继的thr_suspend无效。
Return Values--执行成功后返回0。其他返回值意味着错误。以下情况发生时,thr_suspend()失败并返回相关值。
ESRCH: 在当前进程中找不到target_thread。
Thr_continue(3T)
Thr_continue()恢复执行一个挂起的线程。一旦线程脱离挂起状态,后继的
thr_continue将无效。
#include
int thr_continue(thread_t target_thread);
一个挂起的线程不会被信号唤醒。信号被挂起知道线程被thr-continue恢复执行。
返回值--成功执行后返回0。其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
ESRCH:target_thread在当前进程中找不到。
2.1.5向线程发信号
thr_kill(3T)向线程发信号
#include
#include
int thr_kill(thread_t target_thread,int sig);
thr_kill向线程号为target_thread的线程发送信号sig。Target_thread一定要与调用线程处于同一个进程内。参数sig一定是signal(5)中定义过的。
当sig是0时,错误检查将被执行,没有实际的信号被发送。这可以用来检测arget_thread参数是否合法。
返回值--成功执行后返回0,其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
EINVAL:sig非法;
ESRCH:target_thread找不到;
2.1.6设置本线程的信号掩模
thr_sigsetmask(3T) 获取或改变本线程的信号掩模(signal mask)
#include
#include
int thr_sigsetmask(int how,const sigset_t *set,sigset_t *oset);
how参数决定信号设置将被如何改变,可以是下列值之一:
SIG_BLOCK--在当前信号掩模上增加set,set指要阻塞的信号组。
SIG_UNBLOCK--在当前信号掩模上去掉set,set指要解除阻塞的信号组。
SIG_SETMASK--用新的掩模代替现有掩模,set指新的信号掩模。
当set的值是NULL时,how的值并不重要,信号掩模将不被改变。所以,要查询当前的信号掩模,就给set赋值为NULL。
当参数oset不是NULL时,它指向以前的信号掩模存放的地方。
Return Values--正常执行后返回0。其他值意味着错误。在以下情况发生时, 函数失败并返回相关值。
EINVAL:set不是NULL且how没有被定义;
EFAULT:set或oset不是合法地址;
2.1.7终止线程
thr_exit(3T)
用来终止一个线程。
#include
void thr_exit(void *status);
thr_exit 函数终止当前线程。所有的私有数据被释放。如果调用线程不是一个分离线程,线程的ID和返回状态保留直到有另外的线程在等待。否则返回状态被忽略,线程号被立刻重新使用。
返
2.1线程(函数)库(The Threads Library)
用户级多线程是通过线程库,libthread来实现的(参考手册第3页: library routines)。线程库支持信号,为可运行的程序排队,并负责同 时操纵多任务。
这一章讨论libthread中的一些通用过程,首先接触基本操作,然后循 序渐进地进入更复杂的内容。
创建线程-基本特性 Thr_create(3T)
获得线程号 Thr_self(3T)
执行线程 Thr_yield(3T,the below is same)
挂起或继续线程 Thr_suspend
Thr_continue
向线程送信号 Thr_kill
设置线程的调用掩模 Thr_sigsetmask
终止线程 Thr-exit
等待线程终止 Thr-join
维护线程的私有数据 Thr_keycreate
Thr_setspecific
Thr_getspecific
创建线程-高级特性 Thr_create
获得最小堆栈容量 Thr_min_stack
获得或设置线程的同时性等级 Thr_getconcurrency
Thr_setconcurrency
获得或设置线程的优先级 Thr_getprio
Thr_setprio
2.1.1创建线程-基本篇
thr_create过程是线程库所有过程当中最复杂的一个。这部分的内容仅适用于你使用thr_create的缺省参数来创建进程。
对于thr_create更加复杂的使用,包括如何使用自定参数,我们将在高级特性部分给出说明。
thr_create(3T)
这个函数用于在当前进程中添加一个线程。注意,新的线程不继承未处理的信号,但继承优先级和信号掩模。
#include
int thr_create(void *stack_base,size_t stack_size,
void *(*start_routine) (void*),void *arg,long flags,
thread_t *new_thread);
size_t thr_min_stack(void);
stack_base--新线程的堆栈地址。如果stack_base是空则thr_create()按 照stack_size为新线程分配一个堆栈。
Stack_size--新线程堆栈的字节数。如果本项为0,将使用缺省值,一般 情况下最好将此项设为0。并不是每个线程都需要指定堆栈空间。线程库为每个线程的堆栈分配1M 的虚拟内存,不保留交换空间。(线程库用mmap(2)的MAP_NORESERVE的选项 来实现这种分配)。
Start_routine--指定线程开始执行的函数。如果start_routine返回, 线程将用该函数的返回值作为退出状态而退出。(参考thr_exit(3T))。
Flags--指定新线程的属性,一般设置为0。
Flags的值是通过下列内容的位同或来实现的(最后四个flags在高级特性中给出)。
1. THR_DETACHED 将新线程分离,使得它的线程号和其他资源在线程 结束时即可以回收利用。当你不想等待线程终止时,将其置位。如果没有明确的 同步需求阻碍,一个不挂起的,分离的线程可以在创建者的thr_create返回之前 终止并将其线程号分配给一个心得线程。
2. THR_SUSPENDED挂起新线程,直到被thr_continue唤醒。
3. THR_BOUND把新线程永久绑定在一个LWP上(生成一个绑定线程)。
4. THR_NEW_LWP将非绑定线程的同时性级别加1。
5. THR_DAEMON新线程为一个守护线程。
New_thread--指向存储新线程ID的地址。多数情况下设置为0。
Return Values--thr_create()在成功执行后返回0并退出。任何其他返回值表明有错误发生。当以下情况被检测到时,thr_create()失败并返回响应的值。
EAGAIN :超出了系统限制,例如创建了太多的LWP。
ENOMEM:可用内存不够创建新线程。
EINVAL:stack_base不是NULL而且stack_size比thr_minstack()函数返回的最小堆栈要小。
2.1.2获取线程号
thr_self(3T) 获得自身的线程号。
#include
thread_t thr_self(void)
返回值--调用者的线程号。
2.1.3放弃执行
thr_yield(3T)
thr_yield停止执行当前线程,将执行权限让给有相同或更高优先权的线程。
#include
void thr_yield(void);
2.1.4挂起或继续执行线程
thr_suspend(3T) 挂起线程。
#include
int thr_suspend(thread_t target_thread);
thr_suspend()立即挂起由target_thread指定的线程。在thr_suspend成功返回后,挂起的线程不再执行。后继的thr_suspend无效。
Return Values--执行成功后返回0。其他返回值意味着错误。以下情况发生时,thr_suspend()失败并返回相关值。
ESRCH: 在当前进程中找不到target_thread。
Thr_continue(3T)
Thr_continue()恢复执行一个挂起的线程。一旦线程脱离挂起状态,后继的
thr_continue将无效。
#include
int thr_continue(thread_t target_thread);
一个挂起的线程不会被信号唤醒。信号被挂起知道线程被thr-continue恢复执行。
返回值--成功执行后返回0。其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
ESRCH:target_thread在当前进程中找不到。
2.1.5向线程发信号
thr_kill(3T)向线程发信号
#include
#include
int thr_kill(thread_t target_thread,int sig);
thr_kill向线程号为target_thread的线程发送信号sig。Target_thread一定要与调用线程处于同一个进程内。参数sig一定是signal(5)中定义过的。
当sig是0时,错误检查将被执行,没有实际的信号被发送。这可以用来检测arget_thread参数是否合法。
返回值--成功执行后返回0,其他值意味着错误。在以下情况发生时,函数失败并返回相关值。
EINVAL:sig非法;
ESRCH:target_thread找不到;
2.1.6设置本线程的信号掩模
thr_sigsetmask(3T) 获取或改变本线程的信号掩模(signal mask)
#include
#include
int thr_sigsetmask(int how,const sigset_t *set,sigset_t *oset);
how参数决定信号设置将被如何改变,可以是下列值之一:
SIG_BLOCK--在当前信号掩模上增加set,set指要阻塞的信号组。
SIG_UNBLOCK--在当前信号掩模上去掉set,set指要解除阻塞的信号组。
SIG_SETMASK--用新的掩模代替现有掩模,set指新的信号掩模。
当set的值是NULL时,how的值并不重要,信号掩模将不被改变。所以,要查询当前的信号掩模,就给set赋值为NULL。
当参数oset不是NULL时,它指向以前的信号掩模存放的地方。
Return Values--正常执行后返回0。其他值意味着错误。在以下情况发生时, 函数失败并返回相关值。
EINVAL:set不是NULL且how没有被定义;
EFAULT:set或oset不是合法地址;
2.1.7终止线程
thr_exit(3T)
用来终止一个线程。
#include
void thr_exit(void *status);
thr_exit 函数终止当前线程。所有的私有数据被释放。如果调用线程不是一个分离线程,线程的ID和返回状态保留直到有另外的线程在等待。否则返回状态被忽略,线程号被立刻重新使用。
返
Tags:Solaris,线程,编程,指南,线程,编程

