好了,我前面的一篇blog已经讲过了这个问题。
http://blog.csdn.net/whitetao/article/details/7242712
在Android API < 9时,采用android NDK编译代码是不支持pthread_rwlock_t结构体的。
当时给的解决办法是改写application.mk文件,把版本改成9,APP_PLATFORM := android-9 //对应2.3.1
但是如果我们就需要android 2.2及一下版本支持这个结构体怎么办?
下面将给出解决办法
大家第一点肯定会想,既然不支持,那么我们能否使用android 2.3.1的跟该结构体相关的东东替换掉android2.2版本的呢?
然后我就去查了相关的东东,发现该结构体定义在pthread.h中,代码实现打包在libc.so中,然后进行替换
我试过了,确实是个好办法,编译通过了,但是,我们编译出来的库java层通过jni调用不了了,百思不得其解。
我想了一下,因为libc.so是一些基础库,可能native的一些规则里面也有,两个版本的规则不一致了,所以找不到了。
反正不管它吧,这个方法以失败告终。
好了,再打开android 2.3.1的pthread.h头文件看一下,
就是多定义了一个结构体:
typedef struct {
pthread_mutex_t lock;
pthread_cond_t cond;
int numLocks;
int writerThreadId;
int pendingReaders;
int pendingWriters;
void* reserved[4]; /* for future extensibility */
} pthread_rwlock_t;
还有一些函数:
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abs_timeout);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
其实也就是做读写锁用的,简单来说也就是个互斥的问题。
回头看一下我的代码。
本人看的是webrtc,google的一个开源项目,里面呢封装了一下这个读写锁,定义成自己的工具库使用。
好了,既然知道是什么东东了,那就自己写一个好了:
先看一下webrtc的代码吧:
#include "rw_lock_wrapper.h"
#include <pthread.h>
namespace webrtc {
class RWLockPosix : public RWLockWrapper
{
public:
RWLockPosix();
virtual ~RWLockPosix();
virtual void AcquireLockExclusive();//写锁
virtual void ReleaseLockExclusive();
virtual void AcquireLockShared();//读锁
virtual void ReleaseLockShared();
protected:
virtual int Init();
private:
//pthread_rwlock_t _lock;
};
} // namespace webrtc
好了,既然知道要实现什么功能,自己写一个呗,搞个信号量互斥一下就好了(效率肯定是不如2.3的了,没办法解决多个读,但是至少不会出错了,效率低就低点儿吧)
我随便给贴一个信号量的东西,加进去就好了
CVSemaphore::CVSemaphore(VLONG lCount /* = 1 */, VCHAR *pszName /* = 0 */)
{
sem_init(&m_sem, 0, lCount);
}
CVSemaphore::~CVSemaphore()
{
sem_destroy(&m_sem);
}
VBOOL CVSemaphore::Lock(VUINT32 dwTimeOut /* = -1 */)
{
if ((VUINT32)-1 == dwTimeOut)
{
if (sem_wait(&m_sem))
{
return VFALSE;
}
}
else
{
}
return VTRUE;
}
VBOOL CVSemaphore::Unlock()
{
if (sem_post(&m_sem))
{
return VFALSE;
}
return VTRUE;
}