실행이 잘되는건가요?

­강동우[소프트웨어학부]@Google의 이미지


코드 : 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__

File attachments: 
첨부파일 크기
Image icon 스크린샷, 2020-06-13 16-41-34.png287.35 KB
­강동우[소프트웨어학부]@Google의 이미지

사진 보시다시키 sem_init, sem_wait이 다 undefined reference to 라는 오류같은게 떠서요..

댓글 첨부 파일: 
첨부파일 크기
Image icon 스크린샷, 2020-06-13 16-41-34.png287.35 KB
익명 사용자의 이미지

댓글이 달리지 않는다면, 그 이유에 대해 한번 생각해보시기 바랍니다.

라스코니의 이미지

가능성은  #include <semaphore.h> 가 없다는 것인데요....

ymir의 이미지

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 』

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.