问题描述:
我们的应用程序采用了共享内存和读写锁的机制来实现多进程的并发访问,但测试时发现读写锁有问题,我们所采用的锁是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() 文件)分配的互斥、条件或信号之间进行同步。"
按照上面的操作也是不支持的,必须需要内核的配合才行。