Search
๐Ÿ’พ

16: Lock-based Concurrent Data Structures

course
last review
mastery
none
progress
not started
date
2023/05/02
4 more properties
Previous chapter

Main QUEST

ํŠน์ • ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋ฝ์„ ์ถ”๊ฐ€ํ•ด์•ผ ๊ทธ ์ž๋ฃŒ ๊ตฌ์กฐ๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ? ๋‹ค์ˆ˜์˜ ์Šค๋ ˆ์Šค๊ฐ€ ํ•ด๋‹น ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋„๋ก ํ•ด์„œ ์„ฑ๋Šฅ์„ ์–ด๋–ป๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„๊นŒ?
์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•ด๋„ ๊ฒฝ์Ÿ์กฐ๊ฑด ์—†์ด ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ thread safe์ƒํƒœ๋ผ๊ณ  ํ•œ๋‹ค.
๋˜ํ•œ ์–ผ๋งˆ๋‚˜ ๋™์‹œ์— ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•  ์ง€๋„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋‹ค.

Concurrent Counter

typedef struct __counter_t { int value; pthread_mutex_t lock; } counter_t; void init(counter_t *c) { c->value = 0; pthread_mutex_init(&c->lock, NULL); }
C
๋ณต์‚ฌ
์ผ๋ฐ˜์ ์œผ๋กœ์นด์šดํ„ฐ์šฉ ๋ณ€์ˆ˜ + ๋ฝ์„ ํ•˜๋‚˜์˜ ๊ตฌ์กฐ์ฒด๋กœ ์„ ์–ธํ•˜์—ฌ ๋‹ค๋ฃฌ๋‹ค.
void increment(counter_t *c) { pthread_mutex_lock(&c->lock); c->value++; pthread_mutex_unlock(&c->lock); } void decrement(counter_t *c) { pthread_mutex_lock(&c->lock); c->value--; pthread_mutex_unlock(&c->lock); } int get(counter_t *c) { pthread_mutex_lock(&c->lock); int rc = c->value; pthread_mutex_unlock(&c->lock); return rc; }
C
๋ณต์‚ฌ
ใ…‡
์œ„ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค! (์ผ์ข…์˜ getter์™€ setter๊ฐ™์€ ๋А๋‚Œ์ธ)

Simple, But no Extension

Scalable Counting

โ†’ ๊ผญ ์ •๋ฆฌํ•˜์‹œ์˜คโ€ฆ

Concurrent Linked List

typedef struct __node_t { int key; struct __node_t *next; } node_t; typedef struct __list_t { node_t *head; pthread_mutex_t lock; } list_t; void List_Init(list_t *L) { L->head = NULL; pthread_mutex_init(&L->lock, NULL); }
C
๋ณต์‚ฌ
int List_Insert(list_t *L, int key) { pthread_mutex_lock(&L->lock); node_t *new = malloc(sizeof(node_t)); if (new == NULL) { perror("malloc"); pthread_mutex_unlock(&L->lock); return -1; // fail } new->key = key; new->next = L->head; L->head = new; pthread_mutex_unlock(&L->lock); return 0; // success }
C
๋ณต์‚ฌ
int List_Lookup(list_t *L, int key) { pthread_mutex_lock(&L->lock); node_t *curr = L->head; while (curr) { if (curr->key == key) { pthread_mutex_unlock(&L->lock); return 0; // success } curr = curr->next; } pthread_mutex_unlock(&L->lock); return -1; // failure }
C
๋ณต์‚ฌ

Concurrent Queue

Concurrent Hash Table

Conclusion

Next chapter