Hello! I'm not quite sure this mail was sent to a proper place but anyway I hope I'll get some help :) Trying to understand the way NPTL works I wrote a simple program which uses the base pthread_rwlock functionality (see the attached file). But it doesn't work and I have no idea why. My program contains an integer variable protected with pthread_rwlock. It can execute two simple command: "r" and "w NNN", where NNN is an integer value. When you type 'r' symbol to it's stdin pthread_rwlock_rdlock is being hold for 5 seconds and stored value is being written to the stdout. "w" command holds pthread_rwlock_wrlock for 5 second and changes the data. Here's the text from the pthread_rwlock_rdlock manual :"The pthread_rwlock_rdlock() function shall apply a read lock to the read-write lock referenced by rwlock. The calling thread acquires the read lock if a writer does not hold the lock and (!) there are no writers blocked on the lock (!)." So the expected result for the "r w 10 r" command string is "0 10". But actually it is "0 0". It means that the second "r" command get the lock while the "w" operation is being blocked. I compile my program this way: "gcc main.c -o main -l pthread -std=gnu99" My system info: salmin@salmin:~$ uname -a Linux salmin 2.6.26-1-amd64 #1 SMP Wed Sep 24 13:59:41 UTC 2008 x86_64 GNU/Linux ii gcc 4:4.3.2-2 The GNU C compiler ii libc6 2.7-15 GNU C Library: Shared libraries PS Sorry for my language :) Alexey
#include <stdio.h> #include <pthread.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sched.h> extern char *strerror(int errnum); typedef struct data_t_ { int a; pthread_rwlock_t *restrict rwlock; } data_t; typedef enum query_type_t_ { Q_READ, Q_WRITE, } query_type_t; typedef struct query_t_ { query_type_t type; int a; // if type == Q_WRITE contains data to be written data_t *data; } query_t; void *thread_func(void *arg) { query_t *q = (query_t *)arg; int err; if (q->type == Q_READ) { if (err = pthread_rwlock_rdlock(q->data->rwlock)) { fprintf(stderr, "Can't get read lock: %s\n", strerror(err)); free(q); return (void *)(-1); } printf("%d\n", q->data->a); } else { //Q_WRITE if (err = pthread_rwlock_wrlock(q->data->rwlock)) { fprintf(stderr, "Can't get write lock: %s\n", strerror(err)); free(q); return (void *)(-1); } q->data->a = q->a; } sleep(5); free(q); if (err = pthread_rwlock_unlock(q->data->rwlock)) { fprintf(stderr, "Error during unlocking: %s\n", strerror(err)); return (void *)(-1); } return 0; } int main() { int err; data_t data; data.a = 0; data.rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); if (err = pthread_rwlock_init(data.rwlock, 0)) { fprintf(stderr, "Can't initialize rwlock structure: %s\n", strerror(err)); exit(1); } while (1) { char c; pthread_t pthread; pthread_attr_t pthread_attr; query_t *q = (query_t *)malloc(sizeof(query_t)); q->data = &data; if (scanf("\n%c", &c) != 1 || c == 'q') { break; } if (c == 'r') { q->type = Q_READ; } else if (c == 'w') { int a; q->type = Q_WRITE; if (scanf("%d", &a) != 1) { printf("Numeric data expected\n"); free(q); continue; } q->a = a; } else { printf("Unknown command: %c\n", c); free(q); continue; } if (err = pthread_attr_init(&pthread_attr)) { fprintf(stderr, "Can't initialize pthread_attr structure: %s\n", strerror(err)); exit(1); } /*if (err = pthread_attr_setschedpolicy(&pthread_attr, SCHED_OTHER)) { fprintf(stderr, "Can't set sched policy: %s\n", strerror(err)); exit(1); }*/ if (err = pthread_create(&pthread, &pthread_attr, thread_func, q)) { fprintf(stderr, "Can't create thread: %s\n", strerror(err)); exit(1); } } return 0; }