1. SylixOS trywrlock与Linux差异
在移植Linux的中间件时需要使用中间件自带的测试程序进行测试,在测试线程尝试获取写锁时会遇到理论上应该有错误信息的,而在SylixOS上没有错误提示从而导致测试程序失败。测试模型如程序清单 1.1所示。
程序清单 1.1 线程读写锁测试模型
#include <stdio.h>
#include <pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int main(int argc, char const *argv[])
{
int iRet = -1;
iRet = pthread_rwlock_init(&rwlock, NULL);
if (iRet != 0) {
printf("pthread_rwlock_init failed.\n");
return (-1);
}
iRet = pthread_rwlock_trywrlock(&rwlock);
if (iRet != 0) {
printf("first trywrlock return %d\n", iRet);
return (-1);
}
/*
* do something
*/
iRet = pthread_rwlock_trywrlock(&rwlock);
if (iRet != 0) {
printf("second trywrlock return %d\n", iRet);
return (-1);
}
/*
* do something
*/
pthread_rwlock_destroy(&rwlock);
printf("posix rwlock success!\n");
return (0);
}
Linux上测试结果如图 1.1所示,Linux下在第二次trywrlock时失败(测试时有时候就需要测试错误信息)。
图 1.1 Linux读写锁测试结果
在SylixOS上测试结果如图 1.2所示,程序正常运行。
图 1.2 SylixOS读写锁测试结果
因为测试程序就是针对错误信息进行测试的,所以在SylixOS下该测试用例不通过。
2. 原理分析
根据SylixOS和Linux下的不同测试结果分析可知两者区别便是:同一个线程在第一次获得读写锁后再一次trywrlock时是否返回成功。
2.1 SylixOS读写锁实现
SylixOS线程在第二次trywrlock时做了一个判断,如果该写锁被当前线程使用,则引用计数值加一且返回成功,源码如图 1.1所示。
图 2.1 SylixOS写锁判断
SylixOS认为某个线程之前已经获得写锁,现在该线程需要再次trywrlock则认为获取写锁成功(因为该线程一直拥有写锁)。
2.2 Linux读写锁实现
Linux线程在第二次trywrlock时,发现写锁被使用则直接返回EBUSY(EBUSY=16)即表示出错,源码如图 2.2所示。
图 2.2 Linux写锁实现原理
对于Linux trywrlock而言,只关心能否获得锁。能够获取成功则返回0,发现写锁被使用则返回出错。
3. 总结
SylixOS的trywrlock关注的是当前线程能否进行写操作,而Linux的trywrlock则关注能否获取写锁(如果写锁被占用则返回出错)。