免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2140 | 回复: 1
打印 上一主题 下一主题

Solaris 线程编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 16:19 |只看该作者 |倒序浏览
Solaris 线程编程











本章比较了 Solaris 线程和 POSIX 线程的应用程序编程接口 (application programming interface, API),并介绍了 POSIX 线程中没有的 Solaris 功能。本章讨论以下主题:

比较 Solaris 线程和 POSIX 线程的 API

Solaris 线程的独有函数

相似的同步函数-读写锁

相似的 Solaris 线程函数

相似的同步函数-互斥锁

相似的同步函数:条件变量

相似的同步函数:信号

fork() 和 Solaris 线程的特殊问题

比较 Solaris 线程和 POSIX 线程的 API
Solaris 线程 API 和 pthread API 是同一问题的两种不同解决方案,即在应用程序软件中建立并行性。尽管每个 API 都是完整的,但是可以安全地在同一程序中混合使用 Solaris 线程函数和 pthread 函数。

不过,这两个 API 并不完全匹配。Solaris 线程支持 pthread 中没有的函数,而 pthread 中则包括 Solaris 接口不支持的函数。对于那些匹配的函数,尽管信息内容实际相同,但是关联参数可能并不相同。

通过合并这两个 API,可以使用仅存在于其中一个 API 中的功能来增强另一个 API。同样,在同一个系统中还可以同时运行仅使用 Solaris 线程的应用程序和仅使用 pthread 的应用程序。

API 的主要差异
Solaris 线程和 pthread 在 API 操作和语法方面非常相似。表 8–1 中列出了两者之间的主要差异。

表 8–1 Solaris 线程和 pthread 的独有功能
Solaris 线程
POSIX 线程

使用 thr_ 前缀表示线程函数的名称,使用 sema_ 前缀表示信号函数的名称
使用 pthread_ 前缀表示 pthread 函数的名称,使用 sem_ 前缀表示信号函数的名称

能够创建“守护进程”线程
取消语义

暂停和继续执行线程
调度策略


函数比较表
下表对 Solaris 线程函数和 pthread 函数进行了比较。请注意,即使 Solaris 线程函数和 pthread 函数看上去完全相同,但是其参数可以不同。

如果某个进行比较的接口在 pthread 或 Solaris 线程中不可用,则会在相应的列中显示一个连字符 "-"。pthread 列中后跟 "POSIX.1b" 的各项属于 POSIX 实时标准规范,而不属于 pthread。

表 8–2 Solaris 线程和 POSIX pthread 的比较
Solaris 线程
  1. pthread

  2. thr_create()
  3. pthread_create()

  4. thr_exit()
  5. pthread_exit()

  6. thr_join()
  7. pthread_join()

  8. thr_yield()
  9. sched_yield() POSIX.1b

  10. thr_self()
  11. pthread_self()

  12. thr_kill()
  13. pthread_kill()

  14. thr_sigsetmask()
  15. pthread_sigmask()

  16. thr_setprio()
  17. pthread_setschedparam()

  18. thr_getprio()
  19. pthread_getschedparam()

  20. thr_setconcurrency()
  21. pthread_setconcurrency()

  22. thr_getconcurrency()
  23. pthread_getconcurrency()

  24. thr_suspend()
  25. -

  26. thr_continue()
  27. -

  28. thr_keycreate()
  29. pthread_key_create()

  30. -
  31. pthread_key_delete()

  32. thr_setspecific()
  33. pthread_setspecific()

  34. thr_getspecific()
  35. pthread_getspecific()

  36. -
  37. pthread_once()

  38. -
  39. pthread_equal()

  40. -
  41. pthread_cancel()

  42. -
  43. pthread_testcancel()

  44. -
  45. pthread_cleanup_push()

  46. -
  47. pthread_cleanup_pop()

  48. -
  49. pthread_setcanceltype()

  50. -
  51. pthread_setcancelstate()

  52. mutex_lock()
  53. pthread_mutex_lock()

  54. mutex_unlock()
  55. pthread_mutex_unlock()

  56. mutex_trylock()
  57. pthread_mutex_trylock()

  58. mutex_init()
  59. pthread_mutex_init()

  60. mutex_destroy()
  61. pthread_mutex_destroy()

  62. cond_wait()
  63. pthread_cond_wait()

  64. cond_timedwait()
  65. pthread_cond_timedwait()

  66. cond_reltimedwait()
  67. pthread_cond_reltimedwait_np()

  68. cond_signal()
  69. pthread_cond_signal()

  70. cond_broadcast()
  71. pthread_cond_broadcast()

  72. cond_init()
  73. pthread_cond_init()

  74. cond_destroy()
  75. pthread_cond_destroy()

  76. rwlock_init()
  77. pthread_rwlock_init()

  78. rwlock_destroy()
  79. pthread_rwlock_destroy()

  80. rw_rdlock()
  81. pthread_rwlock_rdlock()

  82. rw_wrlock()
  83. pthread_rwlock_wrlock()

  84. rw_unlock()
  85. pthread_rwlock_unlock()

  86. rw_tryrdlock()
  87. pthread_rwlock_tryrdlock()

  88. rw_trywrlock()
  89. pthread_rwlock_trywrlock()

  90. -
  91. pthread_rwlockattr_init()

  92. -
  93. pthread_rwlockattr_destroy()

  94. -
  95. pthread_rwlockattr_getpshared()

  96. -
  97. pthread_rwlockattr_setpshared()

  98. sema_init()
  99. sem_init() POSIX.1b

  100. sema_destroy()
  101. sem_destroy() POSIX.1b

  102. sema_wait()
  103. sem_wait() POSIX.1b

  104. sema_post()
  105. sem_post() POSIX.1b

  106. sema_trywait()
  107. sem_trywait() POSIX.1b

  108. fork1()
  109. fork()

  110. -
  111. pthread_atfork()

  112. forkall(),多线程副本
  113. -

  114. -
  115. pthread_mutexattr_init()

  116. -
  117. pthread_mutexattr_destroy()

  118. mutex_init() 中的 type 参数
  119. pthread_mutexattr_setpshared()

  120. -
  121. pthread_mutexattr_getpshared()

  122. -
  123. pthread_mutex_attr_settype()

  124. -
  125. pthread_mutex_attr_gettype()

  126. -
  127. pthread_condattr_init()

  128. -
  129. pthread_condattr_destroy()

  130. cond_init() 中的 type 参数
  131. pthread_condattr_setpshared()

  132. -
  133. pthread_condattr_getpshared()

  134. -
  135. pthread_attr_init()

  136. -
  137. pthread_attr_destroy()

  138. thr_create() 中的 THR_BOUND 标志
  139. pthread_attr_setscope()

  140. -
  141. pthread_attr_getscope()

  142. -
  143. pthread_attr_setguardsize()

  144. -
  145. pthread_attr_getguardsize()

  146. thr_create() 中的 stack_size 参数
  147. pthread_attr_setstacksize()

  148. -
  149. pthread_attr_getstacksize()

  150. thr_create() 中的 stack_addr 参数
  151. pthread_attr_setstack()

  152. -
  153. pthread_attr_getstack()

  154. thr_create() 中的 THR_DETACH 标志
  155. pthread_attr_setdetachstate()

  156. -
  157. pthread_attr_getdetachstate()

  158. -
  159. pthread_attr_setschedparam()

  160. -
  161. pthread_attr_getschedparam()

  162. -
  163. pthread_attr_setinheritsched()

  164. -
  165. pthread_attr_getinheritsched()

  166. -
  167. pthread_attr_setsschedpolicy()

  168. -
  169. pthread_attr_getschedpolicy()
复制代码
要使用本章中介绍的用于 Solaris 9 和以前发行版的 Solaris 线程函数,必须使用 Solaris 线程库 -lthread 进行链接。

对于 Solaris 线程和 pthread 来说,即使函数名或参数可能会有所不同,但是操作实际上是相同的。此处仅提供了一个简单的示例,其中包括正确的头文件和函数原型。如果没有为 Solaris 线程函数提供返回值,请参见《man pages section 3: Basic Library Functions》中的相应页以获取函数的返回值。

有关 Solaris 相关函数的更多信息,请参见相关 pthread 文档中以类似方式命名的函数。

如果 Solaris 线程函数所提供的功能在 pthread 中不可用,则会提供这些函数的完整说明。

Solaris 线程的独有函数
本节介绍 Solaris 线程的独有函数:用于暂停执行线程和继续执行暂停的线程。

暂停执行线程
thr_suspend(3C) 可用来立即暂停执行 target_thread 所指定的线程。如果从 thr_suspend() 成功返回,则将不再执行暂停的线程。

因为 thr_suspend() 在暂停目标线程时不会考虑该线程可能持有的锁,所以,在使用 thr_suspend() 时一定要格外小心。如果要暂停的线程调用的函数需要由已暂停的目标线程拥有的锁,则将产生死锁。

thr_suspend 语法
#include <thread.h>int thr_suspend(thread_t tid);
线程暂停之后,以后调用 thr_suspend() 将不起任何作用。信号无法唤醒暂停的线程。线程恢复执行之前,信号将一直保持暂挂状态。

在以下概要中,pthread 中定义的 pthread_t tid 与 Solaris 线程中定义的 thread_t tid 相同。这两个 tid 值可以通过赋值或通过使用强制转换来互换使用。

thread_t tid; /* tid from thr_create() *//* pthreads equivalent of Solaris tid from thread created *//* with pthread_create() */pthread_t ptid; int ret;ret = thr_suspend(tid);/* using pthreads ID variable with a cast */ret = thr_suspend((thread_t) ptid);
thr_suspend 返回值
thr_suspend() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下情况,thr_suspend() 将失败并返回对应的值。

ESRCH

描述:
当前的进程中找不到 tid。

继续执行暂停的线程
thr_continue(3C) 可用来恢复执行暂停的线程。继续执行暂停的线程之后,以后调用 thr_continue() 将不起任何作用。

thr_continue 语法
#include <thread.h>int thr_continue(thread_t tid);
信号无法唤醒暂停的线程。thr_continue() 继续执行暂停的线程之前,信号将一直保持暂挂状态。

在 pthread 中定义的 pthread_t tid 与在 Solaris 线程中定义的 thread_t tid 相同。这两个 tid 值可以通过赋值或通过使用强制转换来互换使用。

thread_t tid; /* tid from thr_create()*//* pthreads equivalent of Solaris tid from thread created *//* with pthread_create()*/pthread_t ptid; int ret;ret = thr_continue(tid);/* using pthreads ID variable with a cast */ret = thr_continue((thread_t) ptid)
thr_continue 返回值
thr_continue() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下情况,thr_continue() 将失败并返回对应的值。

ESRCH

描述:
当前的进程中找不到 tid。

相似的同步函数-读写锁
读写锁允许多个线程同时进行读取访问,但限制每次只能对一个线程进行写入访问。本节讨论了以下主题:

初始化读取器/写入器锁

获取读锁

尝试获取读锁

获取写锁

尝试获取写锁

解除锁定读取器/写入器锁

销毁读取器/写入器锁的状态

一个线程持有读锁时,其他线程也可以获取读锁,但要获取写锁则必须等待。 如果一个线程持有写锁或者正在等待获取写锁,则其他线程必须等待才能获取读锁或写锁。

相比互斥锁,读写锁速度较慢。但是,如果许多并发线程读取使用锁保护的数据,但不经常进行写入,则使用读写锁可以提高性能。

使用读写锁可以同步此进程和其他进程中的线程。读写锁是在可以写入并在协作进程之间共享的内存中分配的。有关针对此行为映射读写锁的信息,请参见 mmap(2) 手册页。

缺省情况下,多个线程正在等待读写锁时,获取锁的顺序是不确定的。但是,为了避免写入器资源匮乏,对于优先级相同的写入器和读取器,Solaris 线程软件包中写入器往往优先于读取器。

读写锁在使用之前必须先初始化。

初始化读写锁
使用 rwlock_init(3C) 可以初始化 rwlp 所指向的读写锁并将锁的状态设置为未锁定。

rwlock_init 语法
#include <synch.h>  (或  #include <thread.h>)int rwlock_init(rwlock_t *rwlp, int type, void * arg);
type 可以是以下值之一:

USYNC_PROCESS。读写锁可用来同步此进程和其他进程中的线程。arg 会被忽略。

USYNC_THREAD。读写锁可用来仅同步此进程中的线程。arg 会被忽略。

同一个读写锁不能同时由多个线程初始化。读写锁还可以通过在清零的内存中进行分配来初始化,在这种情况下假设 type 为 USYNC_THREAD。对于其他线程可能正在使用的读写锁,不得重新初始化。

对于 POSIX 线程,请参见pthread_rwlock_init 语法。

初始化进程内读写锁
#include <thread.h>rwlock_t rwlp;int ret;/* to be used within this process only */ret = rwlock_init(&rwlp, USYNC_THREAD, 0);
初始化进程间读写锁
#include <thread.h>rwlock_t rwlp;int ret;/* to be used among all processes */ret = rwlock_init(&rwlp, USYNC_PROCESS, 0);
rwlock_init 返回值
rwlock_init() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。

论坛徽章:
0
2 [报告]
发表于 2011-12-22 16:42 |只看该作者
学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP