|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
| |
| Solaris2.4 多线程编程指南5--安全和不安全的接口函数 |
[ 作者: Linux联盟收集 加入时间:2006-07-11 19:47:46 来自:Linux联盟收集
] | |
|
5.安全和不安全的接口 VW3Linux联盟 VW3Linux联盟 本章定义了函数和库的多线程安全等级。 VW3Linux联盟 线程安全 VW3Linux联盟 多线程接口安全等级 VW3Linux联盟 异步安全函数 VW3Linux联盟 库的多线程安全等级 VW3Linux联盟 VW3Linux联盟 5.1线程安全 VW3Linux联盟 VW3Linux联盟 线程安全是为了避免数据竞争--数据设置的正确性依赖于多个线程修改数据的顺序。 VW3Linux联盟 如果不需要共享,则给每个线程分配一个私有的数据拷贝。如果数据必须共享,一定要用同步机制来保证操作的唯一性。 VW3Linux联盟 如果一个线程在几个线程同时执行时在逻辑上是正..的。在一个实际的水平上,把安全等级划分为3层比较方便。 VW3Linux联盟 · 不安全 VW3Linux联盟 · 线程安全--非并行 VW3Linux联盟 · 线程安全--多线程安全 VW3Linux联盟 一个不安全的过程可以用在操作前加互斥锁,操作后解互斥锁的办法来使操作序列化(即消除并发)。示例5-1首先显示了一个简化的fputs()的非线程安全实现。 VW3Linux联盟 接下来是用单互斥锁保护使操作序列化的版本。实际上,使用了比需要的更强的同步。如果两个线程调用fputs()来打印到不同的文件时,其中一个用不着等待另一个--它们可以同时操作。 VW3Linux联盟 最后一个版本是多线程安全版。它给每个文件加一个锁,允许两个线程同时指向不同的文件。所以,MT-SAFE(即多线程安全)的函数是线程安全的,并不会使运行性能变坏。 VW3Linux联盟 VW3Linux联盟 Code Example 5-1 线程安全的程度 VW3Linux联盟 /*not thread-safe */ VW3Linux联盟 fputs(const char *s, FILE *stream){ VW3Linux联盟 char *p; VW3Linux联盟 for(p=s; *p; p++) VW3Linux联盟 putc((int)*p,stream); VW3Linux联盟 } VW3Linux联盟 /*serializable*/ VW3Linux联盟 fputs(const char *s,FILE *stream){ VW3Linux联盟 static mutex_t mut; VW3Linux联盟 char *p; VW3Linux联盟 mutex_lock(&m); VW3Linux联盟 for(p=s;*p;p++) VW3Linux联盟 putc((int)*p,stream); VW3Linux联盟 mutex_unlock(&m); VW3Linux联盟 } VW3Linux联盟 /*MT-SAFE*/ VW3Linux联盟 mutex_t m[NFILE]; VW3Linux联盟 fputs(const char *s, FILE *stream){ VW3Linux联盟 static mutex_t mut; VW3Linux联盟 char *p; VW3Linux联盟 mutex_lock(&m[fileno(stream)]); VW3Linux联盟 for (p=s;*p;p++) VW3Linux联盟 putc((int)*p,stream); VW3Linux联盟 mutex_unlock(&m[fileno(stream)]); VW3Linux联盟 } VW3Linux联盟 VW3Linux联盟 5.2多线程接口安全等级 VW3Linux联盟 VW3Linux联盟 man page(3):库函数用下面的分类来描述一个接口支持多线程到什么程度(这些分类在Intro(3) man page中解释地更为详细)。 VW3Linux联盟 Safe 可以被多线程应用程序调用 VW3Linux联盟 Safe with exceptions 例外的部分请参见NOTES部分 VW3Linux联盟 Unsafe 这个接口只有在应用程序保证一个时刻只有一个线程执行时才 VW3Linux联盟 能安全调用 VW3Linux联盟 MT-Safe 完全为多线程设计,不但安全,还支持一些并发性 VW3Linux联盟 MT-Safe with exceptions 例外的部分请参见NOTES部分 VW3Linux联盟 Async-Safe 可以被一个信号控制器安全调用。一个线程在执行Async-Safe函数时被信号中断将不会产生死锁。 VW3Linux联盟 有关safe接口请看附录B的表""MT Safety Levels:Library Interfaces."", 它来自man pages(3)。如果一个第三部分的接口不在表内,它就有可能是不 安全的(不包括源兼容库Source Compatibility Library)。检查man page后才 能确定。 VW3Linux联盟 在""man pages(2):系统调用""中描述的所有函数,除了vfork(2)外都是MT-Safe的。 VW3Linux联盟 一些函数有意地不作成安全,因为如下原因。 VW3Linux联盟 对于单线程的应用程序,MT-Safe回在一定程度上降低性能。 VW3Linux联盟 函数本身有一个不安全接口。例如,一个函数会返回一个指向堆栈缓冲区的指针。你可以用这些函数""再进入""的对等函数???(原文为 VW3Linux联盟 reentrant counterparts)。再进入函数的名字是原函数加""_r""后缀。 VW3Linux联盟 ------------------------------------- VW3Linux联盟 注意--除非通过查询手册页(man pages),否则无法确定一个不以""_r""结尾的 函数是否MT-safe。非MT-safe的函数一定要有同步机制的保护,或者被限制在 初始线程里。 VW3Linux联盟 ------------------------------------ VW3Linux联盟 VW3Linux联盟 *非安全接口的替代(重入 Reentrant)函数 VW3Linux联盟 VW3Linux联盟 对于大多数非安全接口的函数,都存在一个MT-safe的版本。新的MT-safe函数一般是旧的非安全函数加上""_r""后缀。Solaris系统提供以下的""_r""函数。 VW3Linux联盟 VW3Linux联盟 Table 5-1 替代函数 VW3Linux联盟 asctime_r(3C) ctermid_r(3S) ctime_r(3C) VW3Linux联盟 fgetgrent_r(3C) fgetpwent_r(3C) fgetspent_r(3C) VW3Linux联盟 Gamma_r(3M) getgrgid_r(3C) getgrnam_r(3C) VW3Linux联盟 getlogin_r(3C) getpwnam_r(3C) getpwuid_r(3C) VW3Linux联盟 getgrent_r(3C) gethostbyaddr_r(3N) gethostbyname_r(3N) VW3Linux联盟 gethostent_r(3N) getnetbyaddr_r(3N) getnetbyname_r(3N) VW3Linux联盟 getnetent_r(3N) Getprotobyname_r(3N) getprotobynumber_r(3N) VW3Linux联盟 getprotoent_r(3N) getpwent_r(3C) getrpcbyname_r(3N) VW3Linux联盟 getrpcbynumber_r(3N) getrpcent_r(3N) getservbyname_r(3N) VW3Linux联盟 getservbyport_r(3N) getservent_r(3N) getspent_r(3C) VW3Linux联盟 getspnam_r(3C) gmtime_r(3C) lgamma_r(3M) VW3Linux联盟 localtime_(3C)r nis_sperror_r(3N) rand_r(3C) VW3Linux联盟 readdir_r(3C) strtok_r(3C) tmpnam_r(3C) VW3Linux联盟 ttyname_r(3C) VW3Linux联盟 VW3Linux联盟 5.3异步安全函数 VW3Linux联盟 VW3Linux联盟 可以被信号控制器安全调用的函数被称为Async-Safe的。POSIX标准定义并 详列了异步安全函数(IEEE Std 1003.1-1990.3.3.1.3(3)(f), page 55)。除 了POSIX异步安全函数外,下列三个函数也是异步安全的。 VW3Linux联盟 · sema_post(3T) VW3Linux联盟 · thr_sigsetmask(3T) VW3Linux联盟 · thr_kill(3T) VW3Linux联盟 VW3Linux联盟 5.4库的多线程安全等级 VW3Linux联盟 VW3Linux联盟 所有可能被多线程程序的线程调用的函数都应当是MT-Safe的。 VW3Linux联盟 这意味着过程可以同时正确地执行两个操作。所以,每一个被多线程程序使用的接口都应是MT-Safe。 VW3Linux联盟 并不是所有的库都是MT-Safe的。通常被使用的MT-Safe的库详列于表5-2中。其他的库也将最终被改写成MT-Safe的。 VW3Linux联盟 表5-2 一些MT-Safe库 VW3Linux联盟 ------------------------------------ VW3Linux联盟 库 说明 VW3Linux联盟 ------------------------------------ VW3Linux联盟 lib/libc getXXbyYY接口(例如gethostbyname(3N))是MT-Safe的 VW3Linux联盟 lib/libdl_stubs (支持static switch compiling) VW3Linux联盟 lib/libintl VW3Linux联盟 lib/libm 仅当为共享库编译时是MT-Safe的,但与文档库连接时 VW3Linux联盟 不是MT-Safe的 VW3Linux联盟 lib/libmalloc VW3Linux联盟 lib/libmapmalloc VW3Linux联盟 lib/libnsl 包括TLI接口,XDR,RPC客户方和服务方,netdir和 VW3Linux联盟 netselect。 GetXXbyYY是不安全的,但有线程安全版本 VW3Linux联盟 GetXXbyYY_r VW3Linux联盟 lib/libresolv 支持因线程而异的错误码 VW3Linux联盟 lib/libsocket VW3Linux联盟 lib/libw VW3Linux联盟 lib/nametoaddr VW3Linux联盟 lib/nametoaddr VW3Linux联盟 lib/nsswitch VW3Linux联盟 libX11 VW3Linux联盟 libC (不是Solaris系统的部分;可以分开购买) VW3Linux联盟 ------------------------------------ VW3Linux联盟 VW3Linux联盟 *不安全库 VW3Linux联盟 VW3Linux联盟 如果库中的函数不是MT-Safe的,则只有在一个线程的调用时才是安全的。
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|
|
|
|
|