μ΄λ² μ₯μμλ νλ‘μΈμ€λ₯Ό μν μλ‘μ΄ κ°λ μΈ μ°λ λ (Thread) λ₯Ό μκ°νλ€. νλ‘κ·Έλ¨μμ ν μκ°μ νλμ λͺ λ Ήμ΄λ§μ μ€ννλ (λ¨μΌ Program Counter) κ³ μ μ μΈ κ΄μ μμ λ²μ΄λ, λ©ν° μ°λ λ νλ‘κ·Έλ¨μ νλ μ΄μμ μ€ν μ§μ (λ 립μ μΌλ‘ λΆλ¬λ€μ¬μ§κ³ μ€νλ μ μλ μ¬λ¬ κ°μ Program Counter κ°) μ κ°μ§κ³ μλ€.
κ° μ°λ λλ νλ‘μΈμ€μ μ μ¬νμ§λ§ μ°λ λλΌλ¦¬ μ£Όμ 곡κ°μ 곡μ νκΈ° λλ¬Έμ λμΌν κ°μ μ κ·Όν μ μλ€.
νλμ μ°λ λμ μνλ νλ‘μΈμ€μ μ μ¬νκ² μ΄λμ λͺ λ Ήμ΄λ€μ λΆλ¬μ¬μ§ μΆμ νλ PCμ μ°μ°μ μν λ μ§μ€ν°λ₯Ό κ°μ§κ³ μλ€. λ κ°μ μ°λ λκ° νλμ νλ‘μΈμμμ μ€ν μ€μ΄λΌλ©΄ λ λ²μ§Έ μ°λ λλ λ¬Έλ§₯ κ΅νμ ν΅ν΄ 첫 λ²μ§Έ μ°λ λμ κ΅μ²΄λμ΄μΌ νλ€. 첫 λ²μ§Έ μ°λ λκ° μ¬μ©νλ λ μ§μ€ν°λ₯Ό μ μ₯νκ³ , λ λ²μ§Έ μ°λ λκ° μ¬μ©νλ λ μ§μ€ν°μ λ΄μ©μΌλ‘ λλ €λλλ€λ μ μμ νλ‘μΈμ€μ λ¬Έλ§₯ κ΅νκ³Ό μ μ¬νλ€.
νλ‘μΈμ€κ° νλ‘μΈμ€ μ μ΄ λΈλ (PCB) μ μ μ₯νλ―, νλ‘μΈμ€μ μ°λ λλ€μ μνλ₯Ό μ μ₯νκΈ° μν΄ μ°λ λ μ μ΄ λΈλ (TCB) κ° νμνλ€. κ°μ₯ ν° μ°¨μ΄μ μ μ°λ λ κ° λ¬Έλ§₯ κ΅νμμλ μ£Όμ 곡κ°μ κ·Έλλ‘ μ¬μ©νλ€λ μ μ΄λ€.
μ°λ λμ νλ‘μΈμ€μ λ λ€λ₯Έ μ°¨μ΄λ μ€νμ μλ€. λ©ν° μ°λ λ νλ‘μΈμ€μ κ²½μ°μλ, κ° μ°λ λκ° λ 립μ μΌλ‘ μ€νλλ©°, μ£Όμ 곡κ°μλ μ°λ λλ§λ€ μ€νμ΄ ν λΉλμ΄ μλ€.

μ€λ₯Έμͺ½ μ£Όμ 곡κ°μλ λ κ°μ μ€νμ΄ μ‘΄μ¬νλ€. μ€νμμ ν λΉλλ λ³μλ€μ΄λ λ§€κ°λ³μ, 리ν΄κ° λ±μ ν΄λΉ μ°λ λμ μ€νμΈ μ°λ λ-λ‘컬 μ μ₯μ(Thread-local storage) μ μ μ₯λλ€.
μ°λ λ-λ‘컬 μ μ₯μλ‘ μΈν΄ μ κ΅ν μ£Όμ 곡κ°μ λ°°μΉκ° 무λμ Έλ²λ Έλ€. μ€ν μ¬μ΄μ λΉ κ³΅κ°μ΄ μ겨λ²λ Έλ€. μ€νμ ν¬κΈ°κ° μμ£Ό ν¬μ§ μμλ λκΈ° λλ¬Έμ λλΆλΆμ κ²½μ°λ λ¬Έμ κ° λμ§ μλλ€. μ¬κ· νΈμΆμ λ§μ΄ νλ©΄ λ¬Έμ κ° μκΈΈ μ μλ€.
μμ : μ°λ λ μμ±
βAβ, βBβλ₯Ό μΆλ ₯νλ λ 립μ μΈ λ κ°μ μ°λ λλ₯Ό λ§λ€μ΄λ³΄μ.
#include <stdio.h>
#include <assert.h>
#include <pthread.h>
#include "common.h"
#include "common_threads.h"
void *mythread(void *arg) {
printf("%s\n", (char *) arg);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t p1, p2;
int rc;
printf("main: begin\n");
pthread_create(&p1, NULL, mythread, "A");
pthread_create(&p2, NULL, mythread, "B");
// join waits for the threads to finish
pthread_join(p1, NULL);
pthread_join(p2, NULL);
printf("main: end\n");
return 0;
}
mythread() ν¨μλ₯Ό μ€νν λ κ°μ μ°λ λλ₯Ό μμ±νλ€. μ€μΌμ€λ¬κ° μ΄λ»κ² νλλμ λ¬λ €μκΈ΄ νμ§λ§, μ°λ λκ° μμ±λλ©΄ μ¦μ μ€νλ μλ μκ³ , μ€λΉ μνμμ μ€νμ λμ§ μμ μλ μλ€.
λ κ°μ μ°λ λλ₯Ό μμ±ν νμ λ©μΈ μ°λ λλ pthread_join()μ νΈμΆνμ¬ νΉμ μ°λ λμ λμμ μ’
λ£λ₯Ό λκΈ°νλ€.

μ΄λ κ² μ€ν μμλ μ¬λ¬ κ°μ§λ‘ λμ¬ μ μλ€. μ°λ λ 1μ΄ μ°λ λ 2λ³΄λ€ λ¨Όμ μμ±λ κ²½μ°λΌλ, μ€μΌμ€λ¬κ° μ°λ λ 2λ₯Ό λ¨Όμ μ€ννλ©΄ βBβκ° βAβλ³΄λ€ λ¨Όμ μΆλ ₯λ μλ μλ€.
μ°λ λμ μμ±μ΄ ν¨μμ νΈμΆκ³Ό μ μ¬νκ² λ³΄μΈλ€. ν¨μ νΈμΆμμλ ν¨μ μ€ν νμ νΈμΆμ (caller) μκ² λ¦¬ν΄νλ λ°λ©΄, μ°λ λμ μμ±μμλ μ€νν λͺ λ Ήμ΄λ€μ κ°κ³ μλ μλ‘μ΄ μ°λ λκ° μμ±λκ³ , μμ±λ μ°λ λλ callerμλ λ³κ°λ‘ μ€νλλ€. μ°λ λ μμ± ν¨μκ° λ¦¬ν΄λκΈ° μ μ μ°λ λκ° μ€νλ μλ μκ³ , 리ν΄λ μ΄νμ μ°λ λκ° μ€νλ μλ μλ€.
μ΄λ κ² μ°λ λλ μΈμ μ€νλλμ§ μκΈ° μ΄λ ΅λ€.
2. ν¨μ¬ λ μ΄λ €μ΄ μ΄μ : λ°μ΄ν°μ 곡μ
μ μ 곡μ λ³μλ₯Ό κ°±μ νλ λ κ°μ μ°λ λμ λν μμ λ₯Ό μ΄ν΄λ³΄μ.
#include <stdio.h>
#include <pthread.h>
#include "ommon.h"
#include "common_threads.h"
static volatile int counter = 0;
// mythread()
// Simply adds 1 to counter repeatedly, in a loop
// No, this is not how you would add 10,000,000 to
// a counter, but it shows the problem nicely.
void *mythread(void *arg) {
printf("%s: begin\n", (char *) arg);
int i;
for (i = 0; i < 1e7; i++) {
counter = counter + 1;
}
printf("%s: done\n", (char *) arg);
return NULL;
}
// main()
//
// Just launches two threads (pthread_create)
// and then waits for them (pthread_join)
int main(int argc, char *argv[]) {
pthread_t p1, p2;
printf("main: begin (counter = %d)\n", counter);
pthread_create(&p1, NULL, mythread, "A");
pthread_create(&p2, NULL, mythread, "B");
// join waits for the threads to finish
pthread_join(p1, NULL);
pthread_join(p2, NULL);
printf("main: done with both (counter = %d)\n", counter);
return 0;
}
λ€μκ³Ό κ°μ κ²°κ³Όλ₯Ό κΈ°λν κ²μ΄λ€.
1 prompt> gcc βo main main.c βWall βpthread
2 prompt> ./main
3 main: begin (counter = 0)
4 A: begin
5 B: begin
6 A: done
7 B: done
8 main: done with both (counter = 20000000)
νμ§λ§ μ΄ μ½λλ₯Ό μ€ννλ©΄ κΈ°λν λλ‘ κ²°κ³Όκ° μΆλ ₯λμ§ μλλ€.
1 prompt> ./main
2 main: begin (counter = 0)
3 A: begin
4 B: begin
5 A: done
6 B: done
7 main: done with both (counter = 19345221)
λ€μ ν λ² μ€νν΄λ³΄λ©΄, λ λ€λ₯Έ κ²°κ³Όκ° λμ¨λ€.
1 prompt> ./main
2 main: begin (counter = 0)
3 A: begin
4 B: begin
5 A: done
6 B: done
7 main: done with both (counter = 19221041)
μ μ΄λ° μΌμ΄ μΌμ΄λλ κ±ΈκΉ?
3. μ μ΄ μλ μ€μΌμ€λ§
μ μ΄λ° μΌμ΄ μΌμ΄λλμ§ μκΈ° μν΄, μ»΄νμΌλ¬κ° μμ±ν μ½λμ μ€ν μμλ₯Ό μ΄ν΄ν νμκ° μλ€.
x86μμ counterλ₯Ό μ¦κ°νλ μ½λμ μμλ λ€μκ³Ό κ°λ€.
mov 0x8049a1c, %eax
add $0x1, %eax
mov %eax, 0x8049a1c
counter λ³μμ μ£Όμκ° 0x8049a1cμ΄λΌκ³ νμ. mov λͺ
λ Ήμ΄κ° λͺ
μν μ£Όμμ κ°μ μ½μ΄λ€μΈ ν, eax λ μ§μ€ν°μ λ£λλ€. κ·Έλ¦¬κ³ 1μ (0x1) eax λ μ§μ€ν°μ κ°μ λνλ μ°μ°μ ν ν, eax λ μ§μ€ν°μ μ μ₯λ κ·Έ κ°μ λ©λͺ¨λ¦¬μ μλ μ£Όμμ λ€μ μ μ₯νλ€.
λ¬΄μ¨ λ¬Έμ κ° μκΈΈμ§ μμν μ μλ€.
1λ² μ°λ λκ° counterλ₯Ό 1 μ¦κ°μν€λ €κ³ νλ€. counterμ 50μ΄ μ μ₯λμ΄ μμκΈ° λλ¬Έμ, eax λ μ§μ€ν°μ λ£λλ€. eax λ μ§μ€ν°μ 1μ λν΄μ eax λ μ§μ€ν°μ κ°μ΄ 51μ΄ λλ€.
μ΄ λ νμ΄λ¨Έ μΈν°λ½νΈκ° λ°μνμ¬ μ΄μ체μ κ° 1λ² μ°λ λμ PCμ λ μ§μ€ν° λ±μ μνλ₯Ό μ°λ λμ TCBμ μ μ₯νλ€.
κ·Έλ¦¬κ³ 2λ² μ°λ λκ° μ νλκ³ counterλ₯Ό μ¦κ°μν€λ μ½λ μμμ μ§μ
νλ€. μμ§ counterμλ 50μ΄ μ μ₯λμ΄ μκΈ° λλ¬Έμ λκ°μ΄ 50μ μ½κ³ , eax λ μ§μ€ν°μ μ μ₯νκ³ , 1 μ¦κ°μν€κ³ , κ·Έ κ°μ counterμ μ£Όμ 0x8049a1cμ μ μ₯νλ€.
μ°λ λλ κ°λ³μ μΌλ‘ μ°λ λ μ μ© λ μ§μ€ν°λ₯Ό κ°μ§κ³ μλ€. μ¬μ© μ€μ΄λ λ μ§μ€ν°λ€μ μ μ₯νκ³ λ³΅κ΅¬νλ κΈ°λ₯ λλΆμ μ΄ λ μ§μ€ν°λ€μ κ°μνλμ΄ κ° μ°λ λκ° κ°λ³μ μΌλ‘ μ¬μ©ν μ μκ² λλ€.
λ§μ§λ§μΌλ‘ λ¬Έλ§₯ κ΅νμ΄ νλ² λ μΌμ΄λμ 1λ² μ°λ λκ° μ€νλλ€. counterμ μ£Όμ 0x8049a1cμ eax λ μ§μ€ν°μ κ° 51μ μ μ₯νλ€.

μ΄ μμμ²λΌ λͺ λ Ήμ΄μ μ€ν μμμ λ°λΌ κ²°κ³Όκ° λ¬λΌμ§λ μν©μ κ²½μ 쑰건 (race condition) μ΄λΌκ³ νλ€. κ²½μ 쑰건μ μ²ν κ²½μ° μ€νν λλ§λ€ λ€λ₯Έ κ²°κ³Όλ₯Ό μ»λλ€. μ¦, **λΉκ²°μ μ (indeterminate)**μ΄λ€.
λ©ν° μ°λ λκ° κ°μ μ½λλ₯Ό μ€νν λ κ²½μ μ‘°κ±΄μ΄ λ°μνκΈ° λλ¬Έμ μ΄λ¬ν μ½λ λΆλΆμ μκ³ μμ (critical section) μ΄λΌκ³ λΆλ₯Έλ€. 곡μ λ³μλ₯Ό μ κ·Όνκ³ , νλ μ΄μμ μ°λ λμμ λμμ μ€νλλ©΄ μ λλ μ½λλ₯Ό μκ³ μμμ΄λΌ λΆλ₯Έλ€.
μ΄ λ νμν κ²μ μνΈ λ°°μ (mutual exclusion) μ΄λ€. μ΄ μμ±μ νλμ μ°λ λκ° μκ³ μμ λ΄μ μ½λλ₯Ό μ€ν μ€μΌ λλ λ€λ₯Έ μ°λ λκ° μκ³ μμμ μ§μ νλ κ²μ λ§μ μ€νν μ μλλ‘ λ³΄μ₯ν΄ μ€λ€.
4. μμμ±μ λν λ°λ
κ°λ ₯ν λͺ λ Ήμ΄ ν κ°λ‘ μλν λμμ μννμ¬ μΈν°λ½νΈ λ°μ κ°λ₯μ±μ μμ² μ°¨λ¨ν μ μμκΉ?
memoryβadd 0x8049a1c, $0x1
λ©λͺ¨λ¦¬ μμ μμΉμ μ΄λ€ κ°μ λνλ, μμ£Ό κ°λ ₯ν λͺ λ Ήμ΄λ€. μ΄ λͺ λ Ήμ΄κ° μμμ μΌλ‘ μ€νλλ κ²μ 보μ₯νλ€κ³ νμ.
βμμμ (atomic)βμ΄λΌλ μ©μ΄λ μ¬λ¬ κ°μ μμ μ΄λ λͺ λ Ήμ΄ μμ λ κ·Έ μ€ νλμ μμ λλ λͺ λ Ήμ΄ μ€κ°μ μΈν°λ½νΈλκ±°λ μ€λ¨λμ§ μκ³ ν λ²μ μμ ν μ€νλλ κ²μ μλ―Έν©λλ€. μ¦, μμμ μΈ μ°μ°μ βλΆν λΆκ°λ₯βνλ€κ³ λ³Ό μ μμ΅λλ€. μ΄λ νΉν λ³λ ¬ μ²λ¦¬λ λ©ν° μ€λ λ© νκ²½μμ μ€μν κ°λ μ λλ€. μ¬λ¬ μ€λ λ λλ νλ‘μΈμ€κ° λμμ κ°μ λ©λͺ¨λ¦¬ μμΉμ μ κ·Όνλ κ²½μ°, μμμ μ°μ°μ λ°μ΄ν°μ μΌκ΄μ±μ μ μ§νκΈ° μν΄ μ€μν©λλ€.
μ΄λ»κ² νλ©΄
mov 0x8049a1c, %eax
add $0x1, %eax
mov %eax, 0x8049a1c
μ΄λ μμ μμμ μΌλ‘ μ€νν μ μμκΉ? νλμ λͺ λ Ήμ΄λ‘ ν΄κ²°λλ€λ©΄ μ’κ² μ§λ§ μΌλ°μ μΌλ‘λ λΆκ°λ₯νλ€. B-treeμ κ°μ μμμ μΌλ‘ κ°±μ νλ μ΄μ λΈλ¦¬ λͺ λ Ήμ΄κ°μκ² μμκΉ? κ·Έλ° κ±΄ μλ€.
νλμ¨μ΄ λκΈ°ν λͺ λ Ήμ΄μ μ΄μ체μ μ μ§μμ ν΅ν΄ ν λ²μ νλμ μ°λ λλ§ μκ³ μμμμ μ€ννλλ‘ κ΅¬μ±λ, μ λλ‘ μ μλνλ λ©ν° μ°λ λ νλ‘κ·Έλ¨μ μμ±ν μ μλ€.
5. λ λ€λ₯Έ λ¬Έμ : μλ κΈ°λ€λ¦¬κΈ°
μ§κΈκΉμ§λ λ³νμ± λ¬Έμ λ₯Ό 곡μ λ³μ μ κ·Όμ κ΄λ ¨λ μ°λ λ κ°μ μνΈ μμ© λ¬Έμ λ‘ μ μνμμ§λ§, μ€μ λ‘λ νλμ μ°λ λκ° λ€λ₯Έ μ°λ λκ° λμμ μ λΆ λλΌ λκΉμ§ λκΈ°ν΄μΌ νλ μν©λ μΌμ΄λλ€. νλ‘μΈμ€κ° λμ€ν¬ I/Oλ₯Ό μμ²νκ³ μλ΅μ΄ μ¬ λκΉμ§ κΈ°λ€λ¦¬λ κ²½μ° λ±μ΄ μλ€.
6. μ 리: μ μ΄μ체μ μμ?
μ μ΄λ°κ±Έ μ΄μ체μ μμ λ€λ£¨λκ±ΈκΉ? μ΄κ²μ΄ βμμ¬β μ΄κΈ° λλ¬Έμ΄λ€. μ΄μ체μ λ μ΅μ΄μ λ³ν νλ‘κ·Έλ¨μ΄μκ³ μ΄μ체μ λ΄μμ μ¬μ©μ λͺ©μ μΌλ‘ λ€μν κΈ°λ²λ€μ΄ κ°λ°λμλ€. λμ€μλ λ©ν° μ°λ λ νλ‘κ·Έλ¨μ΄ λ±μ₯νλ©΄μ μμ© νλ‘κ·Έλλ¨Έλ€λ μ΄ λ¬Έμ λ₯Ό κ³ λ―Όνκ² λμλ€.
μλ λλ μμ΄ λ°μνλ μΈν°λ½νΈκ° μμ μΈκΈν λͺ¨λ λ¬Έμ λ€μ μμΈμ΄λ€. νμ΄μ§ ν μ΄λΈ, νλ‘μΈμ€ 리μ€νΈ, νμΌ μμ€ν ꡬ쑰 κ·Έλ¦¬κ³ λλΆλΆμ 컀λ μλ£ κ΅¬μ‘°λ€μ΄ μ¬λ°λ₯΄κ² λμνκΈ° μν΄μλ μ μ ν λκΈ°ν ν¨μλ€μ μ¬μ©ν΄μΌ νλ€.