reader writer lock + small cleanups
This commit is contained in:
@@ -8,6 +8,7 @@ SRCS := dining_philosophers_deadlock.c \
|
||||
join.c \
|
||||
binary.c \
|
||||
producer_consumer_works.c \
|
||||
rwlock.c \
|
||||
zemaphore.c
|
||||
|
||||
OBJS := ${SRCS:c=o}
|
||||
|
||||
@@ -43,6 +43,9 @@ prompt> ./producer_consumer 1 1000 1
|
||||
The output should print each produced item once, and show which
|
||||
consumer consumed each produced item.
|
||||
|
||||
# Reader/Writer Locks
|
||||
|
||||
Code in `rwlock.c`. Build via `make`, run via `rwlock`.
|
||||
|
||||
# Dining Philosophers
|
||||
|
||||
@@ -55,3 +58,8 @@ different forms:
|
||||
|
||||
Run `make` to build all of them with the highly primitive `Makefile`.
|
||||
|
||||
|
||||
# Zemaphores
|
||||
|
||||
Code in `zemaphore.c`. We bet you can figure out the rest. This is just
|
||||
a small test of the Zemaphore with the fork/join problem.
|
||||
|
||||
@@ -40,13 +40,14 @@ void eat() {
|
||||
|
||||
void *philosopher(void *arg) {
|
||||
arg_t *args = (arg_t *) arg;
|
||||
int p = args->thread_id;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < args->num_loops; i++) {
|
||||
think();
|
||||
get_forks(args->thread_id);
|
||||
get_forks(p);
|
||||
eat();
|
||||
put_forks(args->thread_id);
|
||||
put_forks(p);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,14 @@ void eat() {
|
||||
|
||||
void *philosopher(void *arg) {
|
||||
arg_t *args = (arg_t *) arg;
|
||||
int p = args->thread_id;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < args->num_loops; i++) {
|
||||
think();
|
||||
get_forks(args->thread_id);
|
||||
get_forks(p);
|
||||
eat();
|
||||
put_forks(args->thread_id);
|
||||
put_forks(p);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
94
threads-sema/rwlock.c
Normal file
94
threads-sema/rwlock.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "common_threads.h"
|
||||
|
||||
typedef struct _rwlock_t {
|
||||
sem_t writelock;
|
||||
sem_t lock;
|
||||
int readers;
|
||||
} rwlock_t;
|
||||
|
||||
void rwlock_init(rwlock_t *lock) {
|
||||
lock->readers = 0;
|
||||
Sem_init(&lock->lock, 1);
|
||||
Sem_init(&lock->writelock, 1);
|
||||
}
|
||||
|
||||
void rwlock_acquire_readlock(rwlock_t *lock) {
|
||||
Sem_wait(&lock->lock);
|
||||
lock->readers++;
|
||||
if (lock->readers == 1)
|
||||
Sem_wait(&lock->writelock);
|
||||
Sem_post(&lock->lock);
|
||||
}
|
||||
|
||||
void rwlock_release_readlock(rwlock_t *lock) {
|
||||
Sem_wait(&lock->lock);
|
||||
lock->readers--;
|
||||
if (lock->readers == 0)
|
||||
Sem_post(&lock->writelock);
|
||||
Sem_post(&lock->lock);
|
||||
}
|
||||
|
||||
void rwlock_acquire_writelock(rwlock_t *lock) {
|
||||
Sem_wait(&lock->writelock);
|
||||
}
|
||||
|
||||
void rwlock_release_writelock(rwlock_t *lock) {
|
||||
Sem_post(&lock->writelock);
|
||||
}
|
||||
|
||||
int read_loops;
|
||||
int write_loops;
|
||||
int counter = 0;
|
||||
|
||||
rwlock_t mutex;
|
||||
|
||||
void *reader(void *arg) {
|
||||
int i;
|
||||
int local = 0;
|
||||
for (i = 0; i < read_loops; i++) {
|
||||
rwlock_acquire_readlock(&mutex);
|
||||
local = counter;
|
||||
rwlock_release_readlock(&mutex);
|
||||
printf("read %d\n", local);
|
||||
}
|
||||
printf("read done: %d\n", local);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *writer(void *arg) {
|
||||
int i;
|
||||
for (i = 0; i < write_loops; i++) {
|
||||
rwlock_acquire_writelock(&mutex);
|
||||
counter++;
|
||||
rwlock_release_writelock(&mutex);
|
||||
}
|
||||
printf("write done\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: rwlock readloops writeloops\n");
|
||||
exit(1);
|
||||
}
|
||||
read_loops = atoi(argv[1]);
|
||||
write_loops = atoi(argv[2]);
|
||||
|
||||
rwlock_init(&mutex);
|
||||
pthread_t c1, c2;
|
||||
Pthread_create(&c1, NULL, reader, NULL);
|
||||
Pthread_create(&c2, NULL, writer, NULL);
|
||||
Pthread_join(c1, NULL);
|
||||
Pthread_join(c2, NULL);
|
||||
printf("all done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user