실행이 잘되는건가요?
코드 : rw-lock.c
#include
#include
#include
#include "common_threads.h"
void *reader(void *arg);
void *writer(void *arg);
typedef struct _rwlock_t {
sem_t writelock;
sem_t mutex;
int AR; // number of Active Readers
} rwlock_t;
void rwlock_init(rwlock_t *rw) {
rw->AR = 0;
Sem_init(&rw->mutex, 1);
Sem_init(&rw->writelock, 1);
}
void rwlock_acquire_readlock(rwlock_t *rw) {
Sem_wait(&rw->mutex);
rw->AR++;
if (rw->AR == 1)
Sem_wait(&rw->writelock);
Sem_post(&rw->mutex);
}
void rwlock_release_readlock(rwlock_t *rw) {
Sem_wait(&rw->mutex);
rw->AR--;
if (rw->AR == 0)
Sem_post(&rw->writelock);
Sem_post(&rw->mutex);
}
void rwlock_acquire_writelock(rwlock_t *rw) {
Sem_wait(&rw->writelock);
}
void rwlock_release_writelock(rwlock_t *rw) {
Sem_post(&rw->writelock);
}
//
// Don't change the code below (just use it!) But fix it if bugs are found!
//
int loops;
int DB = 0;
typedef struct {
int thread_id;
int job_type; // 0: reader, 1: writer
int arrival_delay;
int running_time;
} arg_t;
sem_t print_lock;
#define TAB 10
void space(int s) {
Sem_wait(&print_lock);
int i;
for (i = 0; i < s * TAB; i++)
printf(" ");
}
void space_end() {
Sem_post(&print_lock);
}
#define TICK sleep(1) // 1/100초 단위로 하고 싶으면 usleep(10000)
rwlock_t rwlock;
void *worker(void *arg) {
arg_t *args = (arg_t *)arg;
int i;
for (i = 0; i < args->arrival_delay; i++) {
TICK;
space(args->thread_id); printf("arrival delay %d of %d\n", i, args->arrival_delay); space_end();
}
if (args->job_type == 0) reader(arg);
else if (args->job_type == 1) writer(arg);
else {
space(args->thread_id); printf("Unknown job %d\n",args->thread_id); space_end();
}
return NULL;
}
void *reader(void *arg) {
arg_t *args = (arg_t *)arg;
TICK;
rwlock_acquire_readlock(&rwlock);
// start reading
int i;
for (i = 0; i < args->running_time-1; i++) {
TICK;
space(args->thread_id); printf("reading %d of %d\n", i, args->running_time); space_end();
}
TICK;
space(args->thread_id); printf("reading %d of %d, DB is %d\n", i, args->running_time, DB); space_end();
// end reading
TICK;
rwlock_release_readlock(&rwlock);
return NULL;
}
void *writer(void *arg) {
arg_t *args = (arg_t *)arg;
TICK;
rwlock_acquire_writelock(&rwlock);
// start writing
int i;
for (i = 0; i < args->running_time-1; i++) {
TICK;
space(args->thread_id); printf("writing %d of %d\n", i, args->running_time); space_end();
}
TICK;
DB++;
space(args->thread_id); printf("writing %d of %d, DB is %d\n", i, args->running_time); space_end();
// end writing
TICK;
rwlock_release_writelock(&rwlock);
return NULL;
}
#define MAX_WORKERS 10
int main(int argc, char *argv[]) {
// command line argument로 공급 받거나
// 예: -n 6 -a 0:0:5,0:1:8,1:3:4,0:5:7,1:6:2,0:7:4 또는 -n 6 -a r:0:5,r:1:8,w:3:4,r:5:7,w:6:2,r:7:4
// 아래 코드에서 for-loop을 풀고 배열 a에 직접 쓰는 방법으로 worker 세트를 구성한다.
int num_workers;
pthread_t p[MAX_WORKERS];
arg_t a[MAX_WORKERS];
rwlock_init(&rwlock);
int i;
/*
for (i = 0; i < num_workers; i++) {
a[i].thread_id = i;
a[i].job_type = ...;
a[i].arrival_delay = ...;
a[i].running_time = ...;
}*/
printf("begin\n");
printf(" ... heading ... \n"); // a[]의 정보를 반영해서 헤딩 라인을 출력
for (i = 0; i < num_workers; i++)
Pthread_create(&p[i], NULL, worker, &a[i]);
for (i = 0; i < num_workers; i++)
Pthread_join(p[i], NULL);
printf("end: DB %d\n");
return 0;
}
실행 하기위해선 common_threads.h 필요
코드:
#ifndef __common_threads_h__
#define __common_threads_h__
#include
#include
#include
#ifdef __linux__
#include
#endif
#define Pthread_create(thread, attr, start_routine, arg) assert(pthread_create(thread, attr, start_routine, arg) == 0);
#define Pthread_join(thread, value_ptr) assert(pthread_join(thread, value_ptr) == 0);
#define Pthread_mutex_lock(m) assert(pthread_mutex_lock(m) == 0);
#define Pthread_mutex_unlock(m) assert(pthread_mutex_unlock(m) == 0);
#define Pthread_cond_signal(cond) assert(pthread_cond_signal(cond) == 0);
#define Pthread_cond_wait(cond, mutex) assert(pthread_cond_wait(cond, mutex) == 0);
#define Mutex_init(m) assert(pthread_mutex_init(m, NULL) == 0);
#define Mutex_lock(m) assert(pthread_mutex_lock(m) == 0);
#define Mutex_unlock(m) assert(pthread_mutex_unlock(m) == 0);
#define Cond_init(cond) assert(pthread_cond_init(cond, NULL) == 0);
#define Cond_signal(cond) assert(pthread_cond_signal(cond) == 0);
#define Cond_wait(cond, mutex) assert(pthread_cond_wait(cond, mutex) == 0);
#ifdef __linux__
#define Sem_init(sem, value) assert(sem_init(sem, 0, value) == 0);
#define Sem_wait(sem) assert(sem_wait(sem) == 0);
#define Sem_post(sem) assert(sem_post(sem) == 0);
#endif // __linux__
#endif // __common_threads_h__
첨부 | 파일 크기 |
---|---|
![]() | 287.35 KB |
사진 보시다시키 sem_init, sem_wait이
사진 보시다시키 sem_init, sem_wait이 다 undefined reference to 라는 오류같은게 떠서요..
댓글이 달리지 않는다면, 그 이유에 대해 한번
댓글이 달리지 않는다면, 그 이유에 대해 한번 생각해보시기 바랍니다.
가능성은 #include 가 없다는 것인데요....
가능성은
#include <semaphore.h>
가 없다는 것인데요....음 ..
undefined reference 는 linker error 입니다.
pthread_create 나 sem_init 의 man page 를 보면 -pthread 옵션을 쓰라고 나와 있을겁니다.
-lpthread 를 써도 상관은 없는데, -pthread 와의 차이점은, 단순히 library 를 link 만 할 뿐..
multithreading 과 관련된 기능을 포함하여 몇 가지 플래그가 자동으로 켜지지 않습니다.
가급적이면 -pthread 를 쓰는게 안전합니다.
-lpthread 와 같이 -l 옵션으로 library 를 link 할 때에는 반드시..
object 리스트의 맨 뒤에 넣어줘야 합니다. (본문에서 에러가 난 이유)
예전 버전에서는 어느 위치에 있어도 상관 없었던 것 같은데..
gcc 6 인가 7인가 부터는 위치가 중요해졌습니다.
-l 옵션은 맨 마지막에 주르륵 기술해 주면 됩니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기