diff --git a/src/content/blog/implementing-a-worker-thread-pool-in-c.md b/src/content/blog/implementing-a-worker-thread-pool-in-c.md index 82b707e5f..5db35316d 100644 --- a/src/content/blog/implementing-a-worker-thread-pool-in-c.md +++ b/src/content/blog/implementing-a-worker-thread-pool-in-c.md @@ -188,3 +188,81 @@ void *startThread() { 그런데, 한 스레드가 critical section(임계 영역)에 들어가 걸어 잠그게 되면, 딴 스레드는 계속 손가락만 빨고 있지만 않습니다. `while(true)`에 의해 계속 mutex lock을 얻고, 본인도 임계 영역에 들어가서 걸어 잠글 수 있는지 수시로 확인합니다. 그래서 `htop`으로 각 core를 모니터링했을 때, 모든 코어가 바쁘게 돌아가고 있었던 것입니다.😮 + +## Condition Variable 도입! + +```c +#include +#include +#include +#include +#define NUM_THREADS 4 +typedef struct task { + int a, b; +} Task; + +Task taskQueue[256]; +pthread_mutex_t lockForQueue = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t condForQueue = PTHREAD_COND_INITIALIZER; +int taskCount = 0; + +void enqueueTask(Task task); +void executeTask(Task *task); + +void *startThread(); + +int main() { + pthread_t threads[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; i++) { + if (pthread_create(&threads[i], NULL, startThread, NULL) != 0) { + perror("pthread_create"); + } + } + srand(time(NULL)); + for (int i = 0; i < 100; i++) { + Task task = { + .a = rand() % 100, + .b = rand() % 100, + }; + enqueueTask(task); + } + + for (int i = 0; i < NUM_THREADS; i++) { + if (pthread_join(threads[i], NULL) != 0) { + perror("pthread_join"); + } + } + pthread_mutex_destroy(&lockForQueue); + pthread_cond_destroy(&condForQueue); + return 0; +} +void enqueueTask(Task task) { + pthread_mutex_lock(&lockForQueue); + taskQueue[taskCount++] = task; + pthread_mutex_unlock(&lockForQueue); + pthread_cond_signal(&condForQueue); +} +void executeTask(Task *task) { + int res = task->a + task->b; + printf("the sum of %d and %d is %d\n", task->a, task->b, res); +} + +void *startThread() { + while (true) { + Task task; + pthread_mutex_lock(&lockForQueue); + while (taskCount == 0) { + pthread_cond_wait(&condForQueue, &lockForQueue); + } + + task = taskQueue[0]; + for (int i = 0; i < taskCount - 1; i++) { + taskQueue[i] = taskQueue[i + 1]; + } + taskCount--; + + pthread_mutex_unlock(&lockForQueue); + executeTask(&task); + } +} +```