根据pthread_rwlock_rdlock的POSIX文档“如果编写器没有锁定并且锁上没有写入器阻塞,则调用线程获取读锁定。”我似乎发现即使编写器被阻止也可以获取读锁定。我写的一个小样本的输出如下:
first reader acquiring lock...
first reader lock acquired
first writer acquiring lock...
second reader acquiring lock...
second reader lock acquired
first reader releasing lock
second reader releasing lock
first writer lock acquired
first writer releasing lock
有关我的代码有什么问题,或者我没有正确理解的内容的任何建议? 顺便说一下:
$ make
gcc -g -I. -I../../isilib -c -Wpointer-arith -Wall -pedantic-errors
-D_POSIX_C_SOURCE=200809L -std=c99 -g rwlock_test1.c -o rwlock_test1.o
gcc rwlock_test1.o -L../../isilib -lisi -lrt -lm -pthread -o rwlock_test1
$ uname -a
Linux BLACKHEART 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC
2012 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define PTH_create( a, b, c, d ) \
(pthread_create( (a), (b), (c), (d) ) != 0 ? abort() : (void)0 )
#define PTH_join( a, b ) \
(pthread_join( (a), (b) ) != 0 ? abort() : (void)0 )
#define PTH_rwlock_rdlock( a ) \
(pthread_rwlock_rdlock( (a) ) != 0 ? abort() : (void)0 )
#define PTH_rwlock_wrlock( a ) \
(pthread_rwlock_wrlock( (a) ) != 0 ? abort() : (void)0 )
#define PTH_rwlock_unlock( a ) \
(pthread_rwlock_unlock( (a) ) != 0 ? abort() : (void)0 )
static void *firstReader(
void *arg
);
static void *firstWriter(
void *arg
);
static void *secondReader(
void *arg
);
static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int main( int argc, char **argv )
{
pthread_t thr1;
pthread_t thr2;
pthread_t thr3;
PTH_create( &thr1, NULL, firstReader, NULL );
PTH_create( &thr2, NULL, firstWriter, NULL );
PTH_create( &thr3, NULL, secondReader, NULL );
PTH_join( thr1, NULL );
PTH_join( thr2, NULL );
PTH_join( thr3, NULL );
return 0;
}
static void *firstReader( void *arg )
{
printf( "first reader acquiring lock... \n" );
PTH_rwlock_rdlock( &rwlock );
printf( "first reader lock acquired \n" );
sleep( 10 );
printf( "first reader releasing lock \n" );
PTH_rwlock_unlock( &rwlock );
return NULL;
}
static void *firstWriter( void *arg )
{
sleep( 2 );
printf( "first writer acquiring lock... \n" );
PTH_rwlock_wrlock( &rwlock );
printf( "first writer lock acquired \n" );
sleep( 10 );
printf( "first writer releasing lock \n" );
PTH_rwlock_unlock( &rwlock );
return NULL;
}
static void *secondReader( void *arg )
{
sleep( 5 );
printf( "second reader acquiring lock... \n" );
PTH_rwlock_rdlock( &rwlock );
printf( "second reader lock acquired \n" );
sleep( 5 );
printf( "second reader releasing lock \n" );
PTH_rwlock_unlock( &rwlock );
return NULL;
}
其他信息:
从posix标准:宏_POSIX_THREAD_PRIORITY_SCHEDULING
表示是否支持线程执行调度选项。来自unistd.h
:“如果定义了这些符号,则相应的功能始终可用...”然后列出_POSIX_THREAD_PRIORITY_SCHEDULING
。再次来自posix:“如果支持线程执行调度选项,并且锁中涉及的线程正在使用调度策略SCHED_FIFO
或SCHED_RR
执行,则调用线程不会获取锁定锁定......“所以我有一个程序(如下)在我的Linux系统上显示_POSIX_THREAD_PRIORITY_SCHEDULING
被定义,但我无法强制线程策略SCHED_RR
(我也试过SCHED_FIFO
,bt这没有在节目中显示。)
其他想法?感谢所有...
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define PTH_create( a, b, c, d ) \
(pthread_create( (a), (b), (c), (d) ) != 0 ? abort() : (void)0 )
#define PTH_join( a, b ) \
(pthread_join( (a), (b) ) != 0 ? abort() : (void)0 )
static void *driver(
void *arg
);
int main( int argc, char **argv )
{
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setschedpolicy( &attr, SCHED_RR );
pthread_t thrID;
PTH_create( &thrID, &attr, driver, NULL );
printf( "%ld\n", _POSIX_THREAD_PRIORITY_SCHEDULING );
struct sched_param param;
int policy;
pthread_getschedparam( thrID, &policy, ¶m );
if ( policy == SCHED_FIFO )
puts( "SCHED_FIFO" );
else if ( policy == SCHED_RR )
puts( "SCHED_RR" );
else if ( policy == SCHED_FIFO )
puts( "SCHED_FIFO" );
else if ( policy == SCHED_OTHER )
puts( "SCHED_OTHER" );
else
puts( "eh?" );
PTH_join( thrID, NULL );
return 0;
}
static void *driver( void *arg )
{
sleep( 2 );
return NULL;
}
$ ./sched_test
200809
SCHED_OTHER
答案 0 :(得分:3)
你在POSIX错过了这句话:
如果不支持“线程执行调度”选项,则为 实现 - 定义调用线程是否获取锁 当作家没有持有锁并且有作家被阻止时 锁。
你不能依赖POSIX rwlocks而不是读者而不是读者。
答案 1 :(得分:2)
看起来像Linux pthreads实现中的一个错误。在FreeBSD上正常工作:
first reader acquiring lock...
first reader lock acquired
first writer acquiring lock...
second reader acquiring lock...
first reader releasing lock
first writer lock acquired
first writer releasing lock
second reader lock acquired
second reader releasing lock
答案 2 :(得分:0)
简单地说:
以您的示例为例:
first reader acquiring lock...
→确定,因为没有人拿着锁first reader lock acquired
first writer acquiring lock...
→阻塞,因为读者正在握住锁second reader acquiring lock...
→确定,因为只有读者才持有该锁second reader lock acquired
first reader releasing lock
→第二个阅读器仍处于锁定状态second reader releasing lock
→没有人再握住锁了first writer lock acquired
first writer releasing lock
也没有通用的解决方案:第二个读取器可能会在第一个读取器之前释放锁定,在这种情况下,上述行为将是有益的。否则,第二个读者可能会运行很长时间,而第一个读者和作者很快就会完成工作,在这种情况下,严格按照请求的顺序授予资源将是有益的。