Solaris 线程编程2.....................
Solaris 线程编程2.....................EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 或 arg 指向的地址非法。
获取读锁
使用 rw_rdlock(3C) 可以获取 rwlp 所指向的读写锁中的读锁。
rw_rdlock 语法
#include <synch.h> (或#include <thread.h>)int rw_rdlock(rwlock_t *rwlp);
如果读写锁中的写锁已经锁定,则调用线程将阻塞,直到释放写锁为止。否则,将获取读锁。对于 POSIX 线程,请参见pthread_rwlock_rdlock 语法。
rw_rdlock 返回值
rw_rdlock() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 指向的地址非法。
尝试获取读锁
使用 rw_tryrdlock(3C) 可以尝试获取 rwlp 所指向的读写锁中的读锁。
rw_tryrdlock 语法
#include <synch.h>(或#include <thread.h>)int rw_tryrdlock(rwlock_t *rwlp);
如果读写锁中的写锁已经锁定,则 rw_tryrdlock() 将返回错误。否则,将获取读锁。对于 POSIX 线程,请参见pthread_rwlock_tryrdlock 语法。
rw_tryrdlock 返回值
rw_tryrdlock() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 指向的地址非法。
EBUSY
描述:
rwlp 所指向的读写锁已经锁定。
获取写锁
使用 rw_wrlock(3C) 可以获取 rwlp 所指向的读写锁中的写锁。
rw_wrlock 语法
#include <synch.h>(或#include <thread.h>)int rw_wrlock(rwlock_t *rwlp);
如果读写锁中的读锁或写锁已经锁定,则调用线程将阻塞,直到释放所有的读锁和写锁为止。读写锁中的写锁一次只能由一个线程持有。对于 POSIX 线程,请参见pthread_rwlock_wrlock 语法。
rw_wrlock 返回值
rw_wrlock() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 指向的地址非法。
尝试获取写锁
使用 rw_trywrlock(3C) 可以尝试获取 rwlp 所指向的读写锁中的写锁。
rw_trywrlock 语法
#include <synch.h>(或#include <thread.h>)int rw_trywrlock(rwlock_t *rwlp);
如果读写锁上的读锁或写锁已经锁定,则 rw_trywrlock() 将返回错误。对于 POSIX 线程,请参见pthread_rwlock_trywrlock 语法。
rw_trywrlock 返回值
rw_trywrlock() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 指向的地址非法。
EBUSY
描述:
rwlp 所指向的读写锁已经锁定。
解除锁定读写锁
使用 rw_unlock(3C) 可以解除锁定 rwlp 所指向的读写锁。
rw_unlock 语法
#include <synch.h>(或#include <thread.h>)int rw_unlock(rwlock_t *rwlp);
读写锁必须处于锁定状态,并且调用线程必须持有读锁或写锁。如果还有其他线程正在等待读写锁成为可用,则其中一个线程将被解除阻塞。对于 POSIX 线程,请参见pthread_rwlock_unlock 语法。
rw_unlock 返回值
rw_unlock() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EFAULT
描述:
rwlp 指向的地址非法。
销毁读写锁的状态
使用 rwlock_destroy(3C) 可以销毁与 rlwp 所指向的读写锁相关联的任何状态。
rwlock_destroy 语法
#include <synch.h>(或#include <thread.h>)int rwlock_destroy(rwlock_t *rwlp);
用来存储读写锁的空间不会释放。对于 POSIX 线程,请参见pthread_rwlock_destroy 语法。
示例 8–1 使用银行帐户来说明读写锁。尽管该程序可能会允许多个线程对帐户余额进行并行只读访问,但是仅允许使用一个写入器。请注意,get_balance() 函数需要使用该锁才能确保以原子方式添加支票帐户余额和储蓄帐户余额。
--------------------------------------------------------------------------------
示例 8–1 读写银行帐户
rwlock_t account_lock;float checking_balance = 100.0;float saving_balance = 100.0;...rwlock_init(&account_lock, 0, NULL);...floatget_balance() { float bal; rw_rdlock(&account_lock); bal = checking_balance + saving_balance; rw_unlock(&account_lock); return(bal);}voidtransfer_checking_to_savings(float amount) { rw_wrlock(&account_lock); checking_balance = checking_balance - amount; saving_balance = saving_balance + amount; rw_unlock(&account_lock);}
--------------------------------------------------------------------------------
rwlock_destroy 返回值
rwlock_destroy() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:
参数无效。
EINVAL
描述:
set 不为 NULL,并且 how 的值未定义。
终止线程
使用 thr_exit(3C) 可以终止线程。对于 POSIX 线程,请参见pthread_exit 语法。
thr_exit 语法
#include <thread.h>void thr_exit(void *status);
thr_exit 返回值
thr_exit() 不返回到其调用方。
等待线程终止
使用 thr_join(3C) 可以等待目标线程终止。对于 POSIX 线程,请参见pthread_join 语法。
thr_join 语法
#include <thread.h>int thr_join(thread_t tid, thread_t *departedid, void **status);
目标线程必须是当前进程的成员,而不能是分离线程或守护进程线程。
多个线程不能等待同一个线程完成,否则仅有一个线程会成功完成。其他线程将终止,并返回 ESRCH 错误。
如果目标线程已经终止,thr_join() 将不会阻塞对调用线程的处理。
thr_join,加入特定线程
#include <thread.h>thread_t tid;thread_t departedid;int ret;void *status;/* waiting to join thread "tid" with status */ret = thr_join(tid, &departedid, &status);/* waiting to join thread "tid" without status */ret = thr_join(tid, &departedid, NULL);/* waiting to join thread "tid" without return id and status */ret = thr_join(tid, NULL, NULL);
如果 tid 为 (thread_t)0,则 thread_join() 将等待进程中的任何非分离线程终止。换句话说,如果未指定线程标识符,则任何未分离的线程退出都将导致返回 thread_join()。
thr_join,加入任何线程
#include <thread.h>thread_t tid;thread_t departedid;int ret;void *status;/* waiting to join any non-detached thread with status */ret = thr_join(0, &departedid, &status);
通过在 Solaris thr_join() 中使用 0 来表示线程 ID,进程中的任何非分离线程退出时都将执行加入操作。departedid 表示现有线程的线程 ID。
thr_join 返回值
thr_join() 在成功运行后返回 0。如果检测到以下任一情况,thr_join() 将失败并返回对应的值。
ESRCH
描述:
未找到与目标线程 ID 对应的非分离线程。
EDEADLK
描述:
检测到死锁,或者目标线程的值指定了调用线程。
创建线程特定的数据键
使用 thr_keycreate(3C) 可分配键,用于标识进程中线程特定数据。键可全局应用于进程中的所有线程。创建键时,每个线程都会将一个值与其绑定。
除了函数的名称和参数以外,Solaris 线程的线程特定数据与 POSIX 线程的线程特定数据完全相同。本节概述了 Solaris 函数。 对于 POSIX 线程,请参见pthread_key_create 语法。
thr_keycreate 语法
#include <thread.h>int thr_keycreate(thread_key_t *keyp, void (*destructor) (void *value));
keyp 为每个绑定线程单独维护特定的值。所有的线程最初都会绑定到专用元素 keyp,该元素可用于访问其线程特定数据。创建键时,对于所有活动线程,将为新键赋予值 NULL。此外在创建线程时,还会为以前在新线程中创建的所有键赋予值 NULL。
destructor 函数是可选的,可以将其与每个 keyp 相关联。线程退出时,如果 keyp 具有非 NULL 的 destructor,并且线程具有与 keyp 相关联的非 NULL value,则 destructor 将用当前的关联 value 进行调用。如果线程退出时存在多个 destructor 与其相关,则 destructor 的调用顺序是不确定的。
thr_keycreate 返回值
thr_keycreate() 在成功运行后返回 0。如果检测到以下任一情况,thr_keycreate() 将失败并返回对应的值。
EAGAIN
描述:
系统资源不足,无法创建另一个线程特定的数据键,或者键数目超过了 PTHREAD_KEYS_MAX 的每进程限制。
ENOMEM
描述:
可用内存不足,无法将 value 与 keyp 相关联。
设置线程特定的数据值
thr_setspecific(3C) 可用来将 value 绑定到线程特定的数据键(对于调用线程来说为 key)。对于 POSIX 线程,请参见pthread_setspecific 语法。
thr_setspecific 语法
#include <thread.h>int thr_setspecific(thread_key_t key, void *value);
thr_setspecific 返回值
thr_setspecific() 在成功运行后返回 0。如果检测到以下任一情况,thr_setspecific() 将失败并返回对应的值。
ENOMEM
描述:
可用内存不足,无法将 value 与 keyp 相关联。
EINVAL
描述:
keyp 无效。
获取线程特定的数据值
thr_getspecific(3C) 可用来将当前绑定到调用线程的 key 的值存储到 valuep 所指向的位置。对于 POSIX 线程,请参见pthread_getspecific 语法。
thr_getspecific 语法
#include <thread.h>int thr_getspecific(thread_key_t key, void **valuep);
thr_getspecific 返回值
thr_getspecific() 在成功运行后返回 0。如果检测到以下任一情况,thr_getspecific() 将失败并返回对应的值。
ENOMEM
描述:
可用内存不足,无法将 value 与 keyp 相关联。
EINVAL
描述:
keyp 无效。
设置线程的优先级
在 Solaris 线程中,对于在创建时与父线程具有不同优先级的线程,可以在 SUSPEND 模式下创建。在暂停之后,可以通过使用 thr_setprio(3C) 函数调用来修改线程的优先级。thr_setprio() 完成之后,线程可恢复执行。
争用同步对象时,高优先级的线程优先于低优先级的线程。
thr_setprio 语法
thr_setprio(3C) 可用来将当前进程内 tid 所指定线程的优先级更改为 newprio 所指定的优先级。对于 POSIX 线程,请参见pthread_setschedparam 语法。
#include <thread.h>int thr_setprio(thread_t tid, int newprio)
缺省情况下,线程是基于范围从 0(最不重要)到 127(最重要)的固定优先级来调度的。
thread_t tid;int ret;int newprio = 20;/* suspended thread creation */ret = thr_create(NULL, NULL, func, arg, THR_SUSPENDED, &tid);/* set the new priority of suspended child thread */ret = thr_setprio(tid, newprio);/* suspended child thread starts executing with new priority */ret = thr_continue(tid);
thr_setprio 返回值
thr_setprio() 在成功运行后返回 0。如果检测到以下任一情况,thr_setprio() 将失败并返回对应的值。
ESRCH
描述:
tid 指定的值不引用现有的线程。
EINVAL
描述:
priority 的值对于与 tid 相关联的调度类没有意义。
获取线程的优先级
使用 thr_getprio(3C) 可以获取线程的当前优先级。每个线程都从其创建者继承优先级。thr_getprio() 会将当前的优先级 tid 存储到 newprio 所指向的位置。对于 POSIX 线程,请参见pthread_getschedparam 语法。
thr_getprio 语法
#include <thread.h>int thr_getprio(thread_t tid, int *newprio)
thr_getprio 返回值
thr_getprio() 在成功运行后返回 0。如果检测到以下情况,thr_getprio() 将失败并返回对应的值。
ESRCH
描述:
tid 指定的值不会引用现有的线程。
相似的同步函数-互斥锁
初始化互斥锁
销毁互斥锁
获取互斥锁
释放互斥锁
尝试获取互斥锁
初始化互斥锁
使用 mutex_init(3C) 可以初始化 mp 所指向的互斥锁。对于 POSIX 线程,请参见初始化互斥锁。
mutex_init(3C) 语法
#include <synch.h> #include <thread.h>int mutex_init(mutex_t *mp, int type, void *arg));
type 可以是以下值之一:
USYNC_PROCESS。互斥锁可用来同步此进程和其他进程中的线程。arg 会被忽略。
USYNC_PROCESS_ROBUST。可使用互斥来在此进程和其他进程中可靠地同步线程。arg 会被忽略。
USYNC_THREAD。互斥锁可用来仅同步此进程中的线程。arg 会被忽略。
如果进程在持有 USYNC_PROCESS 锁时失败,该锁以后的请求者都将挂起。对于与客户机进程共享锁的系统,此行为会产生问题,因为客户机进程会异常中止。为了避免出现停用进程所持有的锁定挂起的问题,请使用 USYNC_PROCESS_ROBUST 来锁定互斥锁。USYNC_PROCESS_ROBUST 增加了两个功能:
如果进程停用,则系统将解除锁定该进程所持有的全部锁。
请求失败进程所拥有的任何锁的下一个请求者将获取该锁。但是,拥有该锁时会返回一个错误,指明以前的属主在拥有该锁时失败。
互斥锁还可以通过在清零的内存中进行分配来初始化,在这种情况下假定 type 为 USYNC_THREAD。
多个线程决不能同时初始化同一个互斥锁。如果其他线程正在使用互斥锁,则不得将该互斥锁重新初始化。
进程内的互斥锁
#include <thread.h>mutex_t mp;int ret;/* to be used within this process only */ret = mutex_init(&mp, USYNC_THREAD, 0);
进程间的互斥锁
#include <thread.h>mutex_t mp;int ret;/* to be used among all processes */ret = mutex_init(&mp, USYNC_PROCESS, 0);
强健的进程间互斥
#include <thread.h>mutex_t mp;int ret;/* to be used among all processes */ret = mutex_init(&mp, USYNC_PROCESS_ROBUST, 0);
mutex_init 返回值
mutex_init() 在成功运行后返回 0。如果检测到以下任一情况,mutex_init() 将失败并返回对应的值。
EFAULT
描述:
mp 指向的地址非法。
EINVAL
描述:
mp 指定的值无效。
ENOMEM
描述:
系统内存不足,无法初始化互斥锁。
EAGAIN
描述:
系统资源不足,无法初始化互斥锁。
EBUSY
描述:
系统检测到重新初始化活动互斥锁的尝试。
销毁互斥锁
使用 mutex_destroy(3C) 可以销毁与 mp 所指向的互斥锁相关联的任何状态。用来存储该互斥锁的空间不会释放。对于 POSIX 线程,请参见pthread_mutex_destroy 语法。
mutex_destroy 语法
#include <thread.h>int mutex_destroy (mutex_t *mp);
mutex_destroy 返回值
mutex_destroy() 在成功运行后返回 0。如果检测到以下情况,mutex_destroy() 将失败并返回对应的值。
EFAULT
描述:
mp 指向的地址非法。
获取互斥锁
使用 mutex_lock(3C) 可以锁定 mp 所指向的互斥锁。如果该互斥锁已经锁定,调用线程将会阻塞,直到该互斥锁成为可用为止。调用线程会在具有优先级的队列中等待。对于 POSIX 线程,请参见pthread_mutex_lock 语法。
mutex_lock 语法
#include <thread.h>int mutex_lock(mutex_t *mp);
mutex_lock 返回值
mutex_lock() 在成功运行后返回 0。如果检测到以下任一情况,mutex_lock() 将失败并返回对应的值。
EFAULT
描述:
mp 指向的地址非法。
EDEADLK
描述:
互斥锁已经锁定并且由调用线程拥有。
释放互斥锁
使用 mutex_unlock(3C) 可以解除锁定 mp 所指向的互斥锁。该互斥锁必须锁定。调用线程必须是最后一个锁定该互斥锁的线程,即该互斥锁的属主。对于 POSIX 线程,请参见pthread_mutex_unlock 语法。
mutex_unlock 语法
#include <thread.h>int mutex_unlock(mutex_t *mp);
mutex_unlock 返回值
mutex_unlock() 在成功运行后返回 0。如果检测到以下任一情况,mutex_unlock() 将失败并返回对应的值。
EFAULT
描述:
mp 指向的地址非法。
EPERM
描述:
调用线程不拥有该互斥锁。
尝试获取互斥锁
使用 mutex_trylock(3C) 可以尝试锁定 mp 所指向的互斥锁。此函数是 mutex_lock() 的非阻塞版本。对于 POSIX 线程,请参见pthread_mutex_trylock 语法。
mutex_trylock 语法
#include <thread.h>int mutex_trylock(mutex_t *mp);
mutex_trylock 返回值
mutex_trylock() 在成功运行后返回 0。如果检测到以下任一情况,mutex_trylock() 将失败并返回对应的值。
EFAULT
描述:
mp 指向的地址非法。
EBUSY
描述:
系统检测到重新初始化活动互斥锁的尝试。
相似的同步函数:条件变量
初始化条件变量
销毁条件变量
等待条件
等待绝对时间
等待时间间隔
解除阻塞一个线程
解除阻塞所有线程
初始化条件变量
使用 cond_init(3C) 可以初始化 cv 所指向的条件变量。
cond_init 语法
#include <thread.h>int cond_init(cond_t *cv, int type, int arg);
type 可以是以下值之一:
USYNC_PROCESS。条件变量可用来同步此进程和其他进程中的线程。arg 会被忽略。
USYNC_THREAD。条件变量可用来仅同步此进程中的线程。arg 会被忽略。
条件变量还可以通过在清零的内存中进行分配来初始化,在这种情况下假设 type 为 USYNC_THREAD。
多个线程决不能同时初始化同一个条件变量。对于其他线程可能正在使用的条件变量,不得重新初始化。
对于 POSIX 线程,请参见pthread_condattr_init 语法。
学习了
页:
[1]