2013-05-17 64 views
2

根据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_FIFOSCHED_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, &param); 
    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

你是否为此提交了一个错误? –

+0

尚未...我并没有在我的问题中添加其他信息。 –

+0

您还必须使用'pthread_attr_setschedparam()'设置'sched_priority',因为'SCHED_RR'和'SCHED_FIFO'需要一个非零的'sched_priority'。您还需要确保您的'RLIMIT_RTPRIO'资源限制('ulimit -r')大于或等于您设置的'sched_priority'值。 – caf

回答

2

看起来像在Linux并行线程执行的错误。正确地工作在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 
+0

感谢您的帮助。 –

2

你错过了这句话在POSIX:

如果不支持线程执行计划的选择,它是 实现定义调用线程是否获得锁 时作家不锁定锁定,并且有锁定作家锁定 。

你不能依靠POSIX rwlocks来支持作者而不是读者。

+0

谢谢。我仍然有问题;我为我的问题添加了其他信息。 –

相关问题