問題描述:
我們的應用程式採用了共用記憶體和讀寫鎖的機制來實現多進程的並發訪問,但測試時發現讀寫鎖有問題,我們所採用的鎖是pthread_rwlock_rdlock、pthread_rwlock_wrlock這組函數。
現象:
pthread_rwlockattr_setpshared(&attr,PTHREAD_PROCESS_SHARED);調用出錯,傳回碼38,經查是系統不支援的原因。
系統內容:
uname -a
Linux s12084 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:58:04 EST 2007 i686 i686 i386 GNU/Linux
g++ 3.2.3
問題解決:
因為之前在這種環境運行過,所以懷疑可能是補丁或者系統的版本問題,後來發現 .bash_profile中有下面這行:
export LD_ASSUME_KERNEL=2.4.19 #for build oracle db
原來這是裝oracle 時添加的,當時安裝oracle有問題才加上的。
這種情況下查看關於讀寫鎖的測試程式,此時執行:ldd locktest ,顯示
/lib/libcwait.so (0x00eb0000)
libpthread.so.0 => /lib/i686/libpthread.so.0 (0x003d3000) ----和下面所採用的libpthread不是用的同一個目錄下的庫。
執行 unset LD_ASSUME_KERNEL 後
此時執行:ldd locktest
/lib/libcwait.so (0x00f19000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00b8e000) ---tls目錄所採用的libpthread是能保證讀寫鎖正確性的,上面的不支援讀寫鎖。
通過去掉 LD_ASSUME_KERNEL ,則系統串連到了tls目錄下的libpthread.so.0,此時讀取鎖功能正常了。
關於linux下的線程庫的資料可以參考:
http://www.cublog.cn/u/6303/showart_472641.html 有關於這個問題的詳細的解釋。
通過這個問題,也說明了,linux2.4.19之前的版本 對進程間的讀寫鎖支援是有問題的,或者說是不支援的。
另外http://www.ibm.com/developerworks/cn/linux/porting/solaris/guide1/index.html中提到的:
“
要使用 POSIX 線程的 read/write lock 擴充,您必須在編譯時間定義:
_XOPEN_SOURCE=500
這要在加入 <pthread.h> 標頭檔之前完成,還要定義:
_POSIX_C_SOURCE=199506L
Linux 線程不實現共用進程的互斥、條件和訊號。該擴充的目的是允許不同的進程(有不同地址空間的進程)在共用記憶體中(SVR4 共用記憶體片段或映射的 mmap() 檔案)分配的互斥、條件或訊號之間進行同步。"
按照上面的操作也是不支援的,必須需要核心的配合才行。