GB | BIG5
|
| 首頁 > 編程技術 > C/C++ > 正文 |
 |
| Solaris2.4 多線程編程指南5--安全和不安全的接口函數 |
| 本文出自:BBS水木清華站 作者:Mccartney (coolcat) (2002-01-29 20:32:05) |
5. 安全和不安全的接口 本章定義了函數和庫的多線程安全等級。 線程安全 多線程接口安全等級 異步安全函數 庫的多線程安全等級 5.1線程安全 線程安全是為了避免數據競爭--數據設置的正確性依賴多個線程修改數據的順序。 如果不需要共享,則給每個線程分配一個私有的數據拷貝。如果數據必須共享,一定要用同步機制來保証操作的唯一性。 如果一個線程在幾個線程同時執行時在邏輯上是正..的。在一個實際的水平上,把安全等級劃分為3層比較方便。 ﹒ 不安全 ﹒ 線程安全--非並行 ﹒ 線程安全--多線程安全 一個不安全的過程可以用在操作前加互斥鎖,操作解互斥鎖的辦法來使操作序列化(即消除並發)。示例5-1首先顯示了一個簡化的fputs()的非線程安全實現。 接下來是用單互斥鎖保護使操作序列化的版本。實際上,使用了比需要的更強的同步。如果兩個線程調用fputs()來打印到不同的文件時,其中一個用不著等待另一個--它們可以同時操作。 最一個版本是多線程安全版。它給每個文件加一個鎖,允許兩個線程同時指向不同的文件。所以,MT-SAFE(即多線程安全)的函數是線程安全的,並不會使運行性能變壞。 Code Example 5-1 線程安全的程度 /*not thread-safe */ fputs(const char *s, FILE *stream){ char *p; for(p=s; *p; p++) putc((int)*p,stream); } /*serializable*/ fputs(const char *s,FILE *stream){ static mutex_t mut; char *p; mutex_lock(&m); for(p=s;*p;p++) putc((int)*p,stream); mutex_unlock(&m); } /*MT-SAFE*/ mutex_t m[NFILE]; fputs(const char *s, FILE *stream){ static mutex_t mut; char *p; mutex_lock(&m[fileno(stream)]); for (p=s;*p;p++) putc((int)*p,stream); mutex_unlock(&m[fileno(stream)]); } 5.2多線程接口安全等級 man page(3):庫函數用下面的分類來描述一個接口支持多線程到什程度(這些分類在Intro(3) man page中解釋地更為詳細)。 Safe 可以被多線程應用程序調用 Safe with exceptions 例外的部分請參見NOTES部分 Unsafe 這個接口只有在應用程序保証一個時刻只有一個線程執行時才 能安全調用 MT-Safe 完全為多線程設計,不但安全,還支持一些並發性 MT-Safe with exceptions 例外的部分請參見NOTES部分 Async-Safe 可以被一個信號控制器安全調用。一個線程在執行Async-Safe函數時被信號中斷將不會產生死鎖。 有關safe接口請看附錄B的表"MT Safety Levels:Library Interfaces.", 它來自man pages(3)。如果一個第三部分的接口不在表內,它就有可能是不 安全的(不包括源兼容庫Source Compatibility Library)。檢查man page才 能確定。 在"man pages(2):系統調用"中描述的所有函數,除了vfork(2)外都是MT-Safe的。 一些函數有意地不作成安全,因為如下原因。 對單線程的應用程序,MT-Safe回在一定程度上降低性能。 函數本身有一個不安全接口。例如,一個函數會返回一個指向堆棧緩沖區的指針。你可以用這些函數"再進入"的對等函數???(原文為 reentrant counterparts)。再進入函數的名字是原函數加"_r"綴。 ------------------------------------- 注意--除非通過查詢手冊頁(man pages),否則無法確定一個不以"_r"結尾的 函數是否MT-safe。非MT-safe的函數一定要有同步機制的保護,或者被限制在 初始線程裡。 ------------------------------------ *非安全接口的替代(重入 Reentrant)函數 對大多數非安全接口的函數,都存在一個MT-safe的版本。新的MT-safe函數一般是舊的非安全函數加上"_r"綴。Solaris系統提供以下的"_r"函數。 Table 5-1 替代函數 asctime_r(3C) ctermid_r(3S) ctime_r(3C) fgetgrent_r(3C) fgetpwent_r(3C) fgetspent_r(3C) Gamma_r(3M) getgrgid_r(3C) getgrnam_r(3C) getlogin_r(3C) getpwnam_r(3C) getpwuid_r(3C) getgrent_r(3C) gethostbyaddr_r(3N) gethostbyname_r(3N) gethostent_r(3N) getnetbyaddr_r(3N) getnetbyname_r(3N) getnetent_r(3N) Getprotobyname_r(3N) getprotobynumber_r(3N) getprotoent_r(3N) getpwent_r(3C) getrpcbyname_r(3N) getrpcbynumber_r(3N) getrpcent_r(3N) getservbyname_r(3N) getservbyport_r(3N) getservent_r(3N) getspent_r(3C) getspnam_r(3C) gmtime_r(3C) lgamma_r(3M) localtime_(3C)r nis_sperror_r(3N) rand_r(3C) readdir_r(3C) strtok_r(3C) tmpnam_r(3C) ttyname_r(3C) 5.3異步安全函數 可以被信號控制器安全調用的函數被稱為Async-Safe的。POSIX標準定義並 詳列了異步安全函數(IEEE Std 1003.1-1990.3.3.1.3(3)(f), page 55)。除 了POSIX異步安全函數外,下列三個函數也是異步安全的。 ﹒ sema_post(3T) ﹒ thr_sigsetmask(3T) ﹒ thr_kill(3T) 5.4庫的多線程安全等級 所有可能被多線程程序的線程調用的函數都應當是MT-Safe的。 這意味著過程可以同時正確地執行兩個操作。所以,每一個被多線程程序使用的接口都應是MT-Safe。 並不是所有的庫都是MT-Safe的。通常被使用的MT-Safe的庫詳列表5-2中。其他的庫也將最終被改寫成MT-Safe的。 表5-2 一些MT-Safe庫 ------------------------------------ 庫 說明 ------------------------------------ lib/libc getXXbyYY接口(例如gethostbyname(3N))是MT-Safe的 lib/libdl_stubs (支持static switch compiling) lib/libintl lib/libm 僅當為共享庫編譯時是MT-Safe的,但與文檔庫連接時 不是MT-Safe的 lib/libmalloc lib/libmapmalloc lib/libnsl 包括TLI接口,XDR,RPC客戶方和服務方,netdir和 netselect。 GetXXbyYY是不安全的,但有線程安全版本 GetXXbyYY_r lib/libresolv 支持因線程而異的錯誤碼 lib/libsocket lib/libw lib/nametoaddr lib/nametoaddr lib/nsswitch libX11 libC (不是Solaris系統的部分;可以分開購買) ------------------------------------ *不安全庫 如果庫中的函數不是MT-Safe的,則只有在一個線程的調用時才是安全的。
(http://www.fanqiang.com)
進入【UNIX論壇】
|
|
| 相關文章 |
Solaris2.4 多線程編程指南7--編程指南 (2002-01-29 20:33:46) Solaris2.4 多線程編程指南6--編譯和調試 (2002-01-29 20:32:52) Solaris2.4 多線程編程指南5--安全和不安全的接口函數 (2002-01-29 20:32:05) Solaris2.4 多線程編程指南4--操作系統編程 (2002-01-29 20:29:36) Solaris2.4 多線程編程指南3--使用同步對象編程 (2002-01-29 20:28:07) Solaris2.4 多線程編程指南2--用多線程編程 (2002-01-29 20:26:32) Solaris2.4 多線程編程指南1--線程基礎 (2002-01-29 20:25:25) Linux下的多線程編程 (2001-08-11 09:05:00)
|
|
|
|
 |
★ 樊強制作 歡迎分享 ★ |