๋ฆฌ๋
์ค์์ fork()
ํจ์๋ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ฅผ ๊ทธ๋๋ก ๋ณต์ฌํด ์์ ํ๋ก์ธ์ค๋ฅผ ๋ง๋ญ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ ๋ง๋ก "๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ"๋ฅผ ๋ณต์ฌํ ๊น์?
โ ์๋์! fork()๋ ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ๋ก ๋ณต์ฌํ์ง ์์ต๋๋ค.
โ ๋์ , ํ์ด์ง ํ ์ด๋ธ๋ง ๋ณต์ฌํ๊ณ , ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ ๊ณต์ ํฉ๋๋ค.
๋ฆฌ๋
์ค์์ fork()
ํจ์๋ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ฅผ ๋ณต์ ํ์ฌ ์์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํฉ๋๋ค. ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ๊น์ง ์ ๋ถ ๋ณต์ฌํ๋ฉด ๋๋ฌด ๋๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฒ ์ฃ ? ๊ทธ๋์ ๋ฆฌ๋
์ค๋ ์นดํผ ์จ ๋ผ์ดํธ(Copy-on-Write, CoW) ๊ธฐ๋ฒ์ ํ์ฉํฉ๋๋ค.
ํ๋ก์ธ์ค | ๊ฐ์ ์ฃผ์ | ๋ฌผ๋ฆฌ ์ฃผ์ | ์ฐ๊ธฐ ๊ถํ |
---|---|---|---|
๋ถ๋ชจ | 0~100 | 500~600 | โ |
๋ถ๋ชจ | 100~200 | 600~700 | โ |
์์ | 0~100 | 500~600 | โ |
์์ | 100~200 | 600~700 | โ |
๋ถ๋ชจ์ ์์ ๋ชจ๋ ๊ฐ์ ๋ฌผ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ์ง๋ง, ์ฐ๊ธฐ ๊ถํ์ ์ ๊ฑฐ๋ ์ํ์ ๋๋ค.
์ด ๋ฐฉ์ ๋๋ถ์:
fork()
์คํ์ด ๋งค์ฐ ๋น ๋ฆ
๋๋ค โ
fork()
์งํ ๋ถ๋ชจ์ ์์์ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง๋ง, ์ฐ๊ธฐ ์๋ ์๊ฐ ๋ณต์ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๊ฒ ๋ฐ๋ก Copy-on-Write์
๋๋ค.
ํ์ด์ง ํ ์ด๋ธ ์ํธ๋ฆฌ ๋ด๋ถ์๋ ํ์ด์ง์ ์ฐ๊ธฐ ๊ถํ์ ๊ด๋ฆฌํ๋ ํ๋๊ฐ ์๋๋ฐ, ์ด๋ ๋ถ๋ชจ์ ์์ ์์ชฝ์ ๋์์ผ๋ก ๋ชจ๋ ํ์ด์ง์ ์ฐ๊ธฐ ๊ถํ์ ๋ฌดํจํํฉ๋๋ค.
๋ถ๋ชจ์ ์์: "์ฐ๋ฆฐ ๊ฐ์ ์ฑ
์ ์ฝ๊ณ ์์ด์(์ฝ๊ธฐ ์ ์ฉ)"
์์: "์ฌ๊ธฐ ์ข ๊ณ ์ณ์ผ๊ฒ ์ด!" โ ํ์ด์ง ํดํธ ๋ฐ์!
์ปค๋: "์, ์ ์ฑ
์ค๊ฒ. ๊ฑฐ๊ธฐ๋ค ์จ!"
์ด์์ฒด์ ๋ ํ์ด์ง ํ ์ด๋ธ(Page Table)์ ํตํด ๊ฐ์ ์ฃผ์๋ฅผ ๋ฌผ๋ฆฌ ์ฃผ์๋ก ๋ณํํ ๋ฟ ์๋๋ผ, ๊ฐ ํ์ด์ง์ ๋ํ ์ ๊ทผ ๊ถํ(์ฝ๊ธฐ/์ฐ๊ธฐ/์คํ ๋ฑ)๋ ํจ๊ป ๊ด๋ฆฌํฉ๋๋ค.
ํ์ด์ง ํ ์ด๋ธ์ ๊ฐ ํญ๋ชฉ์ Page Table Entry(PTE)๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ์ฌ๊ธฐ์ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ด์:
ํ๋๋ช | ์ค๋ช |
---|---|
Physical Address | ๋งคํ๋ ๋ฌผ๋ฆฌ ์ฃผ์ |
R (Read) | ์ฝ๊ธฐ ๊ถํ |
W (Write) | ์ฐ๊ธฐ ๊ถํ |
X (Execute) | ์คํ ๊ถํ |
... | ๊ธฐํ ์บ์, ์ ๊ทผ ์ฌ๋ถ ๋ฑ |
fork()
๋ฅผ ํธ์ถํ๋ฉด ์์์ ๋ถ๋ชจ์ ๋ณต์ฌ๋ณธ์ด ๋์ง๋ง, ์ง์ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ณต์ฌํ์ง๋ ์์์.
๋์ ๋ถ๋ชจ์ ์์ ๋ชจ๋ ๊ฐ์ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๊ฒ ๋ฉ๋๋ค.
ํ์ง๋ง ์ด ์ํ์์ ๋๊ตฐ๊ฐ ๊ทธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ ํด๋ฒ๋ฆฌ๋ฉด?
โ ๊ณต์ ์ค์ด๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ง๊ฐ์ง ์ ์์ด์.
๊ทธ๋์!
โ ๋ถ๋ชจ์ ์์์ ํ์ด์ง ํ ์ด๋ธ ๋ชจ๋์์ "์ฐ๊ธฐ ๊ถํ"์ ์ ๊ฑฐํด๋ฒ๋ฆฝ๋๋ค.
์ฆ, ์ฝ๊ธฐ ์ ์ฉ(read-only)์ผ๋ก ๋ง๋ค์ด๋ฒ๋ฆฌ๋ ๊ฑฐ์ฃ .
์ดํ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ์ ๋ ๋ถ๋ชจ์ ์์ ์ฌ์ด์ ๊ณต์ ๋ ๋ฌผ๋ฆฌ ํ์ด์ง์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
ํํธ, ๋ถ๋ชจ์ ์์ ์ค ์ด๋ ์ชฝ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๋ ค๊ณ ํ๋ฉด ํ์ด์ง ๊ณต์ ๋ฅผ ํด์ ํ๊ณ , ํ๋ก์ธ์ค๋ง๋ค ์ ์ฉ ํ์ด์ง
๋ฅผ ๋ง๋ญ๋๋ค. ์์ ํ๋ก์ธ์ค๊ฐ ํ์ด์ง ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๋ฉด ์๋์ ๊ฐ์ ์ผ์ด ์ผ์ด๋ฉ๋๋ค.
โ ์ฆ, ์ฒ์ ์ฐ๋ ์๊ฐ์๋ง ๋ณต์ฌํ๊ณ , ๊ทธ์ ๊น์ง๋ ๊ณต์ ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
fork() ์งํ ๋ถ๋ชจ-์์ ๋ชจ๋ ์ฐ๊ธฐ ๊ถํ์ ์ ๊ฑฐํ๋ ์ด์ ๋, ์ฐ๊ธฐ ์๋ ์์ ๊น์ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๊ฒ ํ๊ธฐ ์ํด์์์!
์์ | ์ํ | ์ค๋ช |
---|---|---|
fork() ์งํ | ๋ถ๋ชจ์ ์์์ ํ์ด์ง์ ๋ชจ๋ ์ฐ๊ธฐ ๊ถํ โ | ๋ฉ๋ชจ๋ฆฌ๋ ๊ณต์ ์ค |
์์์ด ์ฐ๊ธฐ ์๋ | ํ์ด์ง ํดํธ ๋ฐ์ โ ๋ณต์ฌ ๋ฐ์ | ์ด์ ๋ถํฐ ์์์ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ |
๋ถ๋ชจ๋ ๊ทธ๋๋ก | ์์ง ์ฐ๊ธฐ ์ ํ๋ฉด ์ฌ์ ํ ๊ณต์ ์ค | ํจ์จ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ๊ฐ๋ฅ |
100MiB ๋ฉ๋ชจ๋ฆฌ ํ๋ณด ํ fork()
fork ์งํ ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ธ
fork() ํจ์๋ฅผ ํธ์ถ
์์์ด ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ(์ฐ๊ธฐ) โ ๋ค์ ํ์ธ
import mmap, os, subprocess, sys
ALLOC_SIZE = 100*1024*1024
PAGE_SIZE = 4096
def access(data):
for i in range(0, ALLOC_SIZE, PAGE_SIZE):
data[i] = 0
def show_meminfo(msg, who):
print(msg)
subprocess.run("free")
subprocess.run(["ps", "-orss,maj_flt,min_flt", str(os.getpid())])
print()
data = mmap.mmap(-1, ALLOC_SIZE, flags=mmap.MAP_PRIVATE)
access(data)
show_meminfo("*** ์์ ์์ฑ ์ ***", "๋ถ๋ชจ")
pid = os.fork()
if pid == 0:
show_meminfo("*** ์์ ์์ฑ ์งํ ***", "์์")
access(data)
show_meminfo("*** ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํ ***", "์์")
sys.exit(0)
os.wait()
์์ | ์์คํ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ณํ | RSS ๋ณํ | ๋ง์ด๋ ํดํธ ์ |
---|---|---|---|
์์ ์์ฑ ์งํ | ์ฝ 1MiB ์ฆ๊ฐ | ๊ฑฐ์ ๋์ผ | ์ ์ |
์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํ | ์ฝ 100MiB ์ฆ๊ฐ | ์ ์ฌ | ๋งค์ฐ ๋ง์ |
์ฐธ๊ณ : RSS(Resident Set Size) ๋ ํ๋ก์ธ์ค๊ฐ ์ค์ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ(RAM)์์ ์ฐจ์งํ๊ณ ์๋ ํฌ๊ธฐ๋ฅผ ๋งํฉ๋๋ค.
๊ทธ๋ ๊ธฐ์ RSS๋ โ์ค์ ์ ์ ์ค์ธ ๋ฉ๋ชจ๋ฆฌ'์ด๋ผ๊ธฐ๋ณด๋ค๋ RSS๋ ์ค์ ๋ฉ๋ชจ๋ฆฌ ์ ์ ๋์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ๊ณต์ ๋ ๋ฉ๋ชจ๋ฆฌ๋ ํฌํจ๋์ด ์์ด์, ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ(์: ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)๋ฅผ ์ฐ๊ณ ์์ด๋ ๊ฐ์ ๋ฐ๋ก๋ฐ๋ก ๊ณ์ฐํด์.
๐ ๊ทธ๋์ ์ฌ๋ฌ ํ๋ก์ธ์ค์ RSS ๊ฐ์ ๋ค ๋ํ๋ฉด ์ค์ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ ์ดํฉ๋ณด๋ค ํจ์ฌ ํด ์๋ ์์ด์!
์ฆ, RSS ๊ฐ์ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ "๊ณต์ ์ํ"๋ ๊ณ ๋ คํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์๋ก ์ดํดํ๊ธฐ
$ ps -o pid,rss,cmd -p 1234
PID RSS CMD
1234 20480 /usr/bin/python3 myscript.py
โ ์ด๊ฑด 1234๋ฒ ํ๋ก์ธ์ค๊ฐ ์ฝ 20MB์ RAM์ ์ ์ ์ค์ด๋ผ๋ ๋ป์ด์ง๋ง,
๊ทธ ์ค ์ผ๋ถ๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ณต์ ํ๊ณ ์์ ์๋ ์๋ค๋ ์ ์ ์์ง ๋ง์ธ์!
๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์งํ๋ค๊ณผ ๋น๊ต
์ถ์ฒ : https://blog.naver.com/ya3344/221599131853?viewType=pc
์งํ | ์ค๋ช |
---|---|
VSZ (Virtual Set Size) | ํ๋ก์ธ์ค๊ฐ ์ฌ์ฉํ ์ ์๋๋ก ์์ฝ๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ ์ฒด ํฌ๊ธฐ |
RSS (Resident Set Size) | ์ค์ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ ํฌ๊ธฐ (๊ณต์ ํฌํจ) |
PSS (Proportional Set Size) | ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ ํ๋ก์ธ์ค์ ๋น๋กํด์ ๋๋ ๊ณ์ฐํ ๊ฐ (์ ํํจ) |
๐
ps
๋ช ๋ น์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก RSS๋ง ๋ณด์ฌ์ฃผ์ง๋ง, ๋ ์ ํํ ๊ฐ์ ์ํ๋ฉดsmem
์ด๋procfs
์์ PSS๋ฅผ ํ์ธํ๋ ๊ฒ์ด ์ข์์!
[๋ถ๋ชจ & ์์ ํ๋ก์ธ์ค]
๐จ โก๏ธ fork() โก๏ธ ๐ถ
[์ด๊ธฐ ์ํ]
๊ฐ์ ์ฃผ์: ๋์ผ
๋ฌผ๋ฆฌ ์ฃผ์: ๋์ผ
์ฐ๊ธฐ ๊ถํ: โ
[์์์ด ์ฐ๊ธฐ๋ฅผ ์๋]
โ ํ์ด์ง ํดํธ ๋ฐ์
๐ ์ปค๋: ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ
โ
์์ ์ ์ฉ ๋ฉ๋ชจ๋ฆฌ๋ก ์
๋ฐ์ดํธ
Copy-on-Write๋ ์ฐ๊ธฐํ ๋๋ง ์ง์ง ๋ณต์ฌ๋ฅผ ํ๋ ๋๋ํ ์ ๋ต์ด๋ค.
๐ก Demand Paging์ ํ์ํ ๋๋ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉํ๋ ๊ธฐ๋ฒ์ด์์.
์ฒ์๋ถํฐ ๋ค ์ฌ๋ฆฌ๋ ๊ฒ ์๋๋ผ, ์ ๊ทผํ ๋ ํ์ด์ง ํดํธ(Page Fault)๊ฐ ๋ฐ์ํ๋ฉด ๊ทธ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํด์.
์ถ์ฒ : https://www.sitesbay.com/os/os-what-is-demand-paging-in-operating-system
ํ์ด์ง ์ค๋ฅ ํธ๋ฉ
์ด ๋ฐ์ํฉ๋๋ค.์๋ฅผ ๋ค์ด, ํฐ ์ฑ ์ ๋น๋ ธ๋๋ฐ ์ฒ์ ๋ช ์ฅ๋ง ์ฝ์ ๊ฑฐ๋ฉด ๊ตณ์ด ์ ์ฒด๋ฅผ ๋ณต์ฌํ ํ์๊ฐ ์๊ฒ ์ฃ ? ํ์ํ ์ชฝ๋ง ๋ณต์ฌํด๋ ์ถฉ๋ถํ๋๊น์.
execve()
ํจ์๋ ์๋ก์ด ํ๋ก๊ทธ๋จ์ ๋ก๋ฉํ ๋ ์ฌ์ฉ๋ผ์. ์ด ํจ์๊ฐ ํธ์ถ๋๋ฉด:
์ฆ, "์ฝ๋๋ฅผ ์ฝ๋ ์๊ฐ๊น์ง๋ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ ํ ๋น๋์ง ์์ ์ํ"๋ผ๋ ๋ป์ ๋๋ค.
ํ๋ก์ธ์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์กด์ฌํ์ง ์๋ ํ์ด์ง์ ์ ๊ทผํ๋ ค๊ณ ํ ๋, ์ ํจํ์ง ์์ ๊ฒ์ผ๋ก ํ์๋ ํ์ด์ง์ ์ ๊ทผํ๋ฉด ํ์ด์ง ํดํธ ๋๋ ํ์ด์ง ๋๋ฝ ์ธํฐ๋ฝํธ
๊ฐ ๋ฐ์ํฉ๋๋ค. OS๋ ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ๊ธฐ
๋ก ์ ์ด๊ถ์ ๋๊น๋๋ค. ํ์ด์ง ํดํธ ์ธํฐ๋ฝํธ์์ ํ์ธํ๋ฉด ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ํธ์ถํฉ๋๋ค.
์ธํฐ๋ฝํธ ํธ๋ค๋ฌ
๋ ํ์ด์ง ํดํธ(pi)๋ฅผ ๋ฐ์์ํจ ํ์ด์ง ๋ฒํธ๋ฅผ ๊ฐ์ ํธ๋ค๋ฌ์ ์ ๋ฌํฉ๋๋ค. ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋ ์ ๋ชฉ๋ก์ ํ์ธํ๊ณ ํด๋น ํ์ด์ง๋ฅผ ์ค์ ๊ณต๊ฐ์์ ๋ฉ๋ชจ๋ฆฌ๋ก ๋ก๋ํฉ๋๋ค. ์ปค๋
์ ํด๋น ํญ๋ชฉ์ผ๋ก ํ์ด์ง ํ
์ด๋ธ์ ์์ ํ์ฌ ํด๋น ํ์ด์ง๊ฐ ์ ํจํด์ง๋๋ก ํฉ๋๋ค.
์ฐธ๊ณ ๋ก ์ธํฐ๋ฝํธ ํธ๋ค๋ฌ(์์ด: interrupt handler) ๋๋ ์ธํฐ๋ฝํธ ์๋น์ค ๋ฃจํด(์์ด: interrupt Service Routine, ISR)์ ์ธํฐ๋ฝํธ ์ ์์ ์ํด ๋ฐ์๋๋ ์ธํฐ๋ฝํธ์ ๋์ํ์ฌ ํน์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๋ ๊ธฐ๊ณ์ด ์ฝ๋ ๋ฃจํด์ ๋๋ค.
์ถ์ฒ : https://mns010.tistory.com/12
ํญ๋ชฉ | ๋ด์ฉ |
---|---|
๐ ์ง์ฐ ๋ก๋ฉ | ์ค์ ๋ก ์ฐ๊ธฐ ์ ๊น์ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ก๋ฉํ์ง ์์ |
๐พ ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ | ํ์ ์๋ ํ์ด์ง๋ ๋๊น์ง ๋ก๋ฉ๋์ง ์์ ์ ์์ |
๐ ์คํ ์๋ ๊ฐ์ | ํ๋ก๊ทธ๋จ ์คํ ์์ ์์ ํ์ํ ๋ถ๋ถ๋ง ๋ก๋ฉํด์ ๋น ๋ฅด๊ฒ ์์ ๊ฐ๋ฅ |
๐ ์บ์ ํจ์จ | ์์ฃผ ์ ๊ทผํ๋ ํ์ด์ง๋ง ์ ์งํ๋ฉด ์บ์ ํํธ์จ ํฅ์ ๊ฐ๋ฅ |
[1] execve() ํธ์ถ
โ
[2] ํ๋ก๊ทธ๋จ ๋ฉ๋ชจ๋ฆฌ ๋งต ๊ตฌ์ฑ (๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ ์์ง ์์)
โ
[3] ์ฝ๋ ์คํ ์์ โ ์ฒซ ํ์ด์ง ์ ๊ทผ ์ ํ์ด์ง ํดํธ ๋ฐ์
โ
[4] ํด๋น ํ์ด์ง๋ง ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉ (๋๋จธ์ง๋ ์์ง ์์)
โ
[5] ์ดํ ํ์ํ ํ์ด์ง๋ง๋ค on-demand๋ก ๋ฉ๋ชจ๋ฆฌ ๋ก๋ฉ
execve()๋ ๊ฐ์ ์ฃผ์๋ง ์ค๋นํด๋๊ณ , ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ โ์ ๊ทผํ ๋โ ํ๋์ฉ ๋ฐ์์ค๋ ํจ์จ์ ์ธ ์์คํ !
"์ฑ ์ ํ๊บผ๋ฒ์ ๋ค ์ฝ์ง ์๊ณ , ํ์ํ ํ์ด์ง๋ถํฐ ๋๊ธฐ๊ธฐ ์์ํ๋ ๊ฒ๊ณผ ๊ฐ์์!"
์ปดํจํฐ์์ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ์ด ํจ๊ป ์ผํ๋ ค๋ฉด ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ํต์ ์๋จ์ด ํ์ํฉ๋๋ค. ์ด๋ฅผ IPC (Inter-Process Communication, ํ๋ก์ธ์ค ๊ฐ ํต์ )์ด๋ผ๊ณ ํด์.
์ถ์ฒ: https://heeonii.tistory.com/13 [์ฐ๋นํํ ํ์จ์ด๋ค:ํฐ์คํ ๋ฆฌ]
์ ๊ทธ๋ฆผ์ฒ๋ผ ํ๋ก์ธ์ค
๋ ์์ ํ ๋
๋ฆฝ๋ ์คํ๊ฐ์ฒด๋ก์จ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค. ๋
๋ฆฝ๋์ด ์๋ ๋งํผ ๋ณ๋์ ์ค๋น๊ฐ ์์ด ์๋ก๊ฐ์ ํต์ ์ด ์ด๋ ค์,ย ์ปค๋ ์์ญ์์ IPC๋ผ๋ ๋ด๋ถ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ์ ๊ณตํ์ฌ ํ๋ก์ธ์ค๋ ์ปค๋์ด ์ ๊ณตํ๋ IPC์ค๋น๋ฅผ ์ด์ฉํด์ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.ย
๋ฆฌ๋ ์ค๋ ๋ค์ํ IPC ๋ฐฉ์์ ์ง์ํ๋๋ฐ, ๊ทธ์ค์์๋ โ๊ณต์ ๋ฉ๋ชจ๋ฆฌ(shared memory)โ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ์ ์ค ํ๋์ ๋๋ค.
๋จผ์ , ์ผ๋ฐ์ ์ธ fork()
์ดํ ๋ฐ์ดํฐ ๊ณต์ ์์ด ์์์ด ๊ฐ์ ๋ฐ๊ฟจ์ ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
non-shared-memory.py
#!/usr/bin/python3
import os
import sys
data = 1000
print("์์ ํ๋ก์ธ์ค ์์ฑ ์ ๋ฐ์ดํฐ ๊ฐ: {}".format(data))
pid = os.fork()
if pid == 0:
data = 2 # ์์์ด ๊ฐ์ ๋ฐ๊ฟ
sys.exit(0)
os.wait()
print("์์ ํ๋ก์ธ์ค ์ข
๋ฃ ํ ๋ฐ์ดํฐ ๊ฐ: {}".format(data))
์์ ํ๋ก์ธ์ค ์์ฑ ์ ๋ฐ์ดํฐ ๊ฐ: 1000
์์ ํ๋ก์ธ์ค ์ข
๋ฃ ํ ๋ฐ์ดํฐ ๊ฐ: 1000
fork() ํจ์
๋ฅผ ํธ์ถํ ์ดํ์ ๋ถ๋ชจ์ ์์ ํ๋ก์ธ์ค๋ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ค ํ์ชฝ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๋๋ผ๋ ๋ค๋ฅธ ์ชฝ ํ๋ก์ธ์ค์ ์๋ ๋ฐ์ดํฐ์๋ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค.
fork()
๋ ๋ถ๋ชจ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ณต์ฌํ์ง๋ง, Copy-on-Write(CoW) ๋๋ฌธ์ ์ฐ๊ธฐ ์๋ ์ ๋ณต์ ๋ฉ๋๋ค.์ด๋ฒ์ ์์๊ณผ ๋ถ๋ชจ๊ฐ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ฐ๋ผ๋ณด๋๋ก ์ค์ ํด๋ณผ๊ฒ์.
์ถ์ฒ: https://heeonii.tistory.com/13 [์ฐ๋นํํ ํ์จ์ด๋ค:ํฐ์คํ ๋ฆฌ]
๊ณต์ ๋ฉ๋ชจ๋ฆฌ(shared memory)๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ๊ทผํ ์ ์๋๋ก ํด์ฃผ๋ ์ค๋น์ ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก์ธ์ค๋ ์๊ธฐ๋ง์ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง๊ณ ์์ด์. ์ปค๋์ ์ด๋ฅผ ๋ณดํธํด์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์ ๊ทผํ๊ฑฐ๋ ๊ฐ์ญํ์ง ๋ชปํ๊ฒ ํฉ๋๋ค. ํ์ง๋ง ๋๋๋ก, ์๋ก ํ๋ ฅํด์ผ ํ๋ ์ํฉ์์๋ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ฌ์ฉํด์ผ ํ ํ์๊ฐ ์๊ธฐ์ฃ .
โ ํ๋ก์ธ์ค๋ผ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ณ ์ถ๋ค๋ฉด?
๐ง ์๋ ํ๋ฆ
ํญ๋ชฉ | ์ค๋ช |
---|---|
๐งญ ์ง์ ์ ๊ทผ | ์ปค๋์ ์ค์ฌ ์์ด ๋ฉ๋ชจ๋ฆฌ์ ๊ณง๋ฐ๋ก ์ ๊ทผ ๊ฐ๋ฅ |
โก ๋งค์ฐ ๋น ๋ฆ | ๋ชจ๋ IPC ์ค์์ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ์ |
๐ ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ ์์ | ๋จ์ํ ํฌ์ธํฐ๋ก ์ ๊ทผํ๋ฏ๋ก ๋ฌผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ฆ๊ฐํ์ง ์์ |
๐ ์๋ฐฉํฅ ํต์ ๊ฐ๋ฅ | ์ฝ๊ธฐ + ์ฐ๊ธฐ ๋ชจ๋ ๊ฐ๋ฅํ ๊ตฌ์กฐ |
๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ํ๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํจ๊ป ์ฌ์ฉํจ์ผ๋ก์จ, ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ตํ์ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ IPC ๋ฐฉ์์ ๋๋ค.
shared-memory.py
#!/usr/bin/python3
import os, sys, mmap
from sys import byteorder
PAGE_SIZE = 4096
data = 1000
print("์์ ํ๋ก์ธ์ค ์์ฑ ์ ๋ฐ์ดํฐ ๊ฐ: {}".format(data))
# ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ์์ฑ
shared_memory = mmap.mmap(-1, PAGE_SIZE, flags=mmap.MAP_SHARED)
# ์ด๊ธฐ๊ฐ ์ ์ฅ
shared_memory[0:8] = data.to_bytes(8, byteorder)
pid = os.fork()
if pid == 0:
# ์์์ด ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ณ 2๋ฐฐ๋ก ๋ง๋ค๊ธฐ
data = int.from_bytes(shared_memory[0:8], byteorder)
data *= 2
shared_memory[0:8] = data.to_bytes(8, byteorder)
sys.exit(0)
os.wait()
# ๋ถ๋ชจ๊ฐ ๊ฐ ํ์ธ
data = int.from_bytes(shared_memory[0:8], byteorder)
print("์์ ํ๋ก์ธ์ค ์ข
๋ฃ ํ ๋ฐ์ดํฐ ๊ฐ: {}".format(data))
์์ ํ๋ก์ธ์ค ์์ฑ ์ ๋ฐ์ดํฐ ๊ฐ: 1000
์์ ํ๋ก์ธ์ค ์ข
๋ฃ ํ ๋ฐ์ดํฐ ๊ฐ: 2000
mmap()
์ MAP_SHARED
ํ๋๊ทธ์ ํจ๊ป ์ฐ๋ฉด, ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ํ๋ก์ธ์ค ๊ฐ ๊ณต์ ๋ฉ๋๋ค.๋ง์น ๋ถ๋ชจ์ ์์์ด ๊ฐ์ ์น ํ์ ๋ณด๊ณ ๊ธ์จ๋ฅผ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์์.
์์์ด 1000์ 2000์ผ๋ก ๋ฐ๊ฟ ์ฐ๋ฉด, ๋ถ๋ชจ๊ฐ ๊ทธ๊ฑธ ๊ณ ์ค๋ํ ๋ณผ ์ ์๊ฒ ์ฃ ?
๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ ๋ถ๋ชจ์ ์์์ด ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ณด๊ฒ ํด์, ๋ฐ์ดํฐ๊ฐ ์ ๋ง๋ก '๊ณต์ '๋๋๋ก ๋ง๋ค์ด์ค๋๋ค!
์ถ์ฒ : https://hasumang.tistory.com/11
์๊ทธ๋(Signal)์ ๋ฆฌ๋ ์ค์์ ํ๋ก์ธ์ค ๊ฐ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ ํธ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
ํ๋ก์ธ์ค์๊ฒ ์ด๋ค ์ฌ๊ฑด์ด ๋ฐ์ํ์์ ์๋ ค์ฃผ๋ ๊ฐ๋จํ ๋ฉ์์ง ์ญํ ์ ํด์.
์๊ทธ๋ ์ด๋ฆ | ์๋ฏธ |
---|---|
SIGINT | ์ธํฐ๋ฝํธ (Ctrl+C) |
SIGTERM | ์ข ๋ฃ ์์ฒญ |
SIGKILL | ๊ฐ์ ์ข ๋ฃ (kill -9) |
์ด ์๊ทธ๋๋ค์ ์ฉ๋๊ฐ ์ ํด์ง ์์คํ ์๊ทธ๋์ด์์. ์ฌ์ฉ์ ํ๋ก๊ทธ๋จ์ด ์์๋ก ํด์ํ์ง ์๊ณ , ์์คํ ์ด ์๋ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
SIGUSR1
, SIGUSR2
์ฌ์ฉ์๊ฐ ์ง์ ์ ์ํด์ ์ธ ์ ์๋ ์๊ทธ๋๋ ์์ด์!
SIGUSR1
, SIGUSR2
๋ ์ฌ์ฉ์ ์ ์ ์๊ทธ๋์
๋๋ค.์๋ฅผ ๋ค๋ฉด, ํ๋ก์ธ์ค A๊ฐ B์๊ฒ โ์ง๊ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ค์ด์ผโ, ๋๋ โ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐโ๋ผ๋ ์ ํธ๋ฅผ ๋ณด๋ด๋ ์์ด์ฃ .
ํน์ง | ์ค๋ช |
---|---|
โ ๋จ์ํจ | ์๊ทธ๋์ ์ค์ง "์๋ค"๋ ์ฌ์ค๋ง ์๋ฆผ |
โ ๋ฐ์ดํฐ ์ ๋ฌ ๋ถ๊ฐ | ์๊ทธ๋๋ง์ผ๋ก๋ ์์น๋ ๋ฌธ์์ด ๋ฑ ์ค์ ๋ฐ์ดํฐ๋ ์ ์ก ๋ถ๊ฐ |
โ ๋ณ๋ ์๋จ ํ์ | ๋ฐ๋ผ์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ผ๋ ค๋ฉด ๊ณต์ ๋ฉ๋ชจ๋ฆฌ, ํ์ดํ ๋ฑ ๋ค๋ฅธ IPC ๋ฐฉ์๊ณผ ํจ๊ป ์ฌ์ฉํด์ผ ํจ |
dd
๋ช
๋ น์ด์ ์๊ทธ๋ ๋ณด๋ด๊ธฐ๋ฆฌ๋
์ค์ dd
๋ช
๋ น์ด๋ SIGUSR1 ์๊ทธ๋์ ๋ฐ์ผ๋ฉด ๋ณต์ฌ ์งํ ์ํ๋ฅผ ์ถ๋ ฅํ๋ ์จ์ ๊ธฐ๋ฅ์ด ์์ด์.
$ dd if=/dev/zero of=test bs=1 count=1G &
[1] 2992194 # ๋ฐฑ๊ทธ๋ผ์ด๋ PID
$ DDPID=$! # ์ต๊ทผ ๋ฐฑ๊ทธ๋ผ์ด๋ PID ์ ์ฅ
$ kill -SIGUSR1 $DDPID
# ์ถ๋ ฅ:
8067496+8 records in
8067496+0 records out
8067496 bytes (8.1 MB, 7.7 MiB) copied, 15.3716 s, 525 kB/s
kill -SIGUSR1
์ dd ํ๋ก์ธ์ค์ "์ํ ์ถ๋ ฅํด์ค!"๋ผ๊ณ ์ ํธ๋ฅผ ๋ณด๋ธ ๊ฑฐ์์.SIGUSR1
์ ์ฌ๋ฌ ๋ฒ ๋ณด๋ด๋ฉด ์ค๊ฐ์ค๊ฐ ์งํ ์ํฉ์ ๊ณ์ ์ ์ ์์ฃ !์๊ทธ๋์ ํ๋ก์ธ์ค์๊ฒ '๋ฌด์ธ๊ฐ ์ผ์ด๋ฌ์ด!'๋ผ๊ณ ์๋ ค์ฃผ๋ ๋จ์ํ ์๋ฆผ ๋๊ตฌ์ด๋ฉฐ,
๋ณต์กํ ํต์ ๋ณด๋ค๋ ๊ฐ๋จํ ํธ๋ฆฌ๊ฑฐ์ฉ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ข์ต๋๋ค! ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์ต๋ช ํ์ดํ(Anonymous Pipe)์ ๋ช ๋ช ๋ ํ์ดํ(Named Pipe)์ ๊ฐ๋ ๊ณผ ์ฐจ์ด๋ฅผ ์ค์ฌ์ผ๋ก, ๋ฐํ๋ ๋ธ๋ก๊ทธ์ฉ์ผ๋ก ๋ณด๊ธฐ ์ข๊ณ ์ดํดํ๊ธฐ ์ฌ์ด ๋ฐฉ์์ผ๋ก ์ ๋ฆฌํด๋๋ฆด๊ฒ์.
ํ์ดํ(pipe)๋ ํ ํ๋ก์ธ์ค์ ์ถ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ ๋ ฅ์ผ๋ก ์ ๋ฌํ๋ ํต์ ์๋จ์ ๋๋ค.
๋ฆฌ๋ ์ค์์๋ ์์์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ ์์ฃผ ์ฌ์ฉํ์ฃ :
$ free | awk '(NR==2){print $2}'
free
: ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด๋ฅผ ์ถ๋ ฅ|
: ํ์ดํ โ free
์ ์ถ๋ ฅ์ awk
์ ์
๋ ฅ์ผ๋ก ์ ๋ฌawk
: ์ ๋ฌ๋ฐ์ ์
๋ ฅ์์ ํน์ ํ๋๋ง ์ถ์ถํ์ดํ๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฅ ์น์ํ ์๋ฅผ ๋ค์๋ฉด
bash ๊ฐ์ ์ ธ์์ ๋ฌธ์๋ก ํ๋ก๊ทธ๋จ๋ผ๋ฆฌ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฐ๊ณํ๋ ๊ฒ
์ด์ฒ๋ผ ํ์ดํ๋ ๊ฐ๋จํ๊ณ ์ง๊ด์ ์ธ ๋จ๋ฐฉํฅ ํต์ ์๋จ์ผ๋ก ์์ํ์ง๋ง, ํ๋ก์ธ์ค ๊ฐ ํต์ (IPC)์์๋ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
์๋ฐฉํต์ ์ ์ํด์๋ Write์ฉ PIPEํ๋ Read PIPEํ๋๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค. read()์write()๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก block ๋ชจ๋๋ก ์๋ํ๊ธฐ ๋๋ฌธ์ ํ๋ก์ธ์ค๊ฐ read๊ฐ ๋๊ธฐ์ค์ด๋ผ๋ฉด read๊ฐ ๋๋๊ธฐ ์ ์๋ write๋ฅผ ํ ์๊ฐ ์๊ฒ ๋ฉ๋๋ค.
ํญ๋ชฉ | ์ค๋ช |
---|---|
ํน์ง | ์ด๋ฆ์ด ์๋ ์์์ ์ธ ํ์ดํ |
ํต์ ๋ฐฉ์ | ๋จ๋ฐฉํฅ |
์ฌ์ฉ ์กฐ๊ฑด | ๊ณตํต ๋ถ๋ชจ๋ฅผ ๊ฐ์ง ํ๋ก์ธ์ค ๊ฐ (ex. ๋ถ๋ชจ-์์) |
์์ฑ ํจ์ | pipe() ์์คํ
์ฝ |
๋ฐ์ดํฐ ํ๋ฆ | FIFO (๋จผ์ ์ด ๊ฒ ๋จผ์ ์ฝํ) |
์ ํ | ๊ฐ์ ๋ถ๋ชจ๋ฅผ ๊ฐ์ง ํ๋ก์ธ์ค ๊ฐ์๋ง ์ฌ์ฉ ๊ฐ๋ฅ |
r, w = os.pipe()
os.write(w, b'hello')
print(os.read(r, 5)) # b'hello'
read()
๊ฐ ๋๊ธฐ ์ค์ด๋ฉด write()
๋ ๋งํ๋๋คNamed Pipe(๋ช ๋ช ๋ ํ์ดํ)๋ ์ด๋ฆ์ด ๋ถ์ฌ๋ ํ์ผ์ ํตํด ์ ํ ๊ด๋ จ ์๋ ํ๋ก์ธ์ค๋ผ๋ฆฌ๋ ํต์ ํ ์ ์๋๋ก ํด์ฃผ๋ ๋ฆฌ๋ ์ค IPC(ํ๋ก์ธ์ค ๊ฐ ํต์ ) ๋ฐฉ์์ ๋๋ค.
ํญ๋ชฉ | ์ค๋ช |
---|---|
ํน์ง | ์ด๋ฆ์ด ์๋ ํ์ดํ ํ์ผ์ ํตํด ํต์ |
ํต์ ๋ฐฉ์ | ๋จ๋ฐฉํฅ |
์ฌ์ฉ ์กฐ๊ฑด | ์์ ํ ๋ ๋ฆฝ์ ์ธ ํ๋ก์ธ์ค ๊ฐ์๋ ์ฌ์ฉ ๊ฐ๋ฅ |
์์ฑ ๋ฐฉ๋ฒ | mkfifo() ์์คํ
์ฝ ๋๋ mkfifo ๋ช
๋ น์ด |
๋ฐ์ดํฐ ํ๋ฆ | FIFO ๊ตฌ์กฐ |
ํ์ผ ์์คํ ์ ์กด์ฌ | โ (ex. /tmp/mypipe ) |
ํญ๋ชฉ | ์ต๋ช ํ์ดํ (Anonymous) | ๋ช ๋ช ๋ ํ์ดํ (Named) |
---|---|---|
์ด๋ฆ | ์์ | ์์ (/tmp/mypipe ๋ฑ) |
์ฌ์ฉ ๋ฒ์ | ๋ถ๋ชจ-์์ ๊ด๊ณ์ ํ๋ก์ธ์ค๋ง ์ฌ์ฉ ๊ฐ๋ฅ | ์์ ํ ๋ณ๊ฐ์ ํ๋ก์ธ์ค๋ ์ฌ์ฉ ๊ฐ๋ฅ |
์์ฑ ๋ฐฉ์ | pipe() ํจ์ | mkfifo ๋ช
๋ น์ด ๋๋ mkfifo() ํจ์ |
์กด์ฌ ์์น | ๋ฉ๋ชจ๋ฆฌ ๋ด๋ถ | ํ์ผ ์์คํ ์์ ํ์ผ๋ก ์์ฑ๋จ |
$ mkfifo /tmp/mypipe
/tmp/mypipe
๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง ํ์ดํ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.ํฐ๋ฏธ๋ 1 (์ฐ๊ธฐ ์ธก)
$ echo "์๋
ํ๋ก์ธ์ค B!" > /tmp/mypipe
ํฐ๋ฏธ๋ 2 (์ฝ๊ธฐ ์ธก)
$ cat < /tmp/mypipe
์๋
ํ๋ก์ธ์ค B!
read()
์ write()
๋ ๊ธฐ๋ณธ์ ์ผ๋ก blocking ๋ชจ๋์
๋๋ค.pipeAtoB
, pipeBtoA
์ถ์ฒ: https://heeonii.tistory.com/13 [์ฐ๋นํํ ํ์จ์ด๋ค:ํฐ์คํ ๋ฆฌ]
# ํ์ดํ ์์ฑ
$ mkfifo mypipe
# ํฐ๋ฏธ๋ 1
$ echo "Hello" > mypipe
# ํฐ๋ฏธ๋ 2
$ cat < mypipe
Hello
ํญ๋ชฉ | ์ต๋ช ํ์ดํ (Anonymous Pipe) | ๋ช ๋ช ๋ ํ์ดํ (Named Pipe) |
---|---|---|
์ด๋ฆ | ์์ | ์์ (ํ์ผ ์์คํ ์ ์์ฑ) |
์์ฑ ๋ฐฉ์ | pipe() | mkfifo() ๋๋ ๋ช
๋ น์ด mkfifo |
์ฌ์ฉ ๋ฒ์ | ๋ถ๋ชจ-์์ ๋ฑ ๊ด๋ จ๋ ํ๋ก์ธ์ค | ์ ํ ๋ค๋ฅธ ํ๋ก์ธ์ค ๊ฐ์๋ ์ฌ์ฉ ๊ฐ๋ฅ |
๋ฐฉํฅ์ฑ | ๋จ๋ฐฉํฅ (์๋ฐฉํฅ์ 2๊ฐ ํ์) | ๋จ๋ฐฉํฅ (์๋ฐฉํฅ์ 2๊ฐ ํ์) |
์ฐ๊ฒฐ | ํ์ผ ๊ธฐ์ ์(File Descriptor) ๊ธฐ๋ฐ | ํ์ผ ๊ฒฝ๋ก(Path) ๊ธฐ๋ฐ |
์ต๋ช ํ์ดํ๋ ๊ด๋ จ๋ ํ๋ก์ธ์ค๋ผ๋ฆฌ, ๋ช ๋ช ๋ ํ์ดํ๋ ์ด๋ฆ๋ง ์๋ฉด ๋๊ตฌ๋ ํต์ ๊ฐ๋ฅ!
์ถ์ฒ : https://heeonii.tistory.com/13
๊ทธ๋ ๋ค๋ฉด ์๋ฐฉํฅ ํต์ ์ด ๊ฐ๋ฅํ ๊ตฌ์กฐ๋? ์์ผ
ํญ๋ชฉ | ๊ธฐ๋ณธ ํน์ง |
---|---|
ํต์ ๋ฐฉํฅ | ๋จ๋ฐฉํฅ (ํ์ชฝ์ ์ฐ๊ธฐ, ํ์ชฝ์ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ) |
์๋ฐฉํฅ ๊ตฌํ | ์ฝ๊ธฐ์ฉ ํ์ดํ + ์ฐ๊ธฐ์ฉ ํ์ดํ 2๊ฐ ๋ง๋ค์ด์ผ ํจ |
์ฐจ๋จ ํน์ฑ | ๊ธฐ๋ณธ์ ์ผ๋ก read() / write() ๋ ๋ธ๋กํน I/O |
โ ๊ทธ๋์ ๊ธฐ๋ณธ
pipe()
๋๋mkfifo()
๋ง ์ฌ์ฉํ๋ฉด ์ง์ ํ ์๋ฐฉํฅ ํต์ ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
ํ์ดํ๋ณด๋ค ํ ๋จ๊ณ ์งํํ ๊ตฌ์กฐ๋ก, ํ๋์ ์ฐ๊ฒฐ๋ง์ผ๋ก ์๋ฐฉํฅ ํต์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
ํญ๋ชฉ | ์ค๋ช |
---|---|
์๋ฐฉํฅ ํต์ | O (ํ ๊ฐ์ ์์ผ์ผ๋ก read/write ๋ชจ๋ ๊ฐ๋ฅ) |
ํ๋ก์ธ์ค ๊ด๊ณ | ๊ด๊ณ ์๋ ํ๋ก์ธ์ค๋ผ๋ฆฌ๋ ์ฌ์ฉ ๊ฐ๋ฅ |
๊ตฌํ ๋ฐฉ์ | socketpair() ๋๋ AF_UNIX ์์ผ |
์ฑ๋ฅ | ๋น ๋ฅด๊ณ , ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๋ ํจ์จ์ |
๐ ๋ฆฌ๋
์ค์ socketpair(AF_UNIX, SOCK_STREAM)
ํจ์๋ ์ค์ ๋ก ์๋ฐฉํฅ ํ์ดํ๋ฅผ ๊ตฌํํ ๊ฒ์ผ๋ก ๋ณด์๋ฉด ๋ฉ๋๋ค.
int fd[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
// fd[0]๊ณผ fd[1] ๋ชจ๋ ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ฐ๋ฅ!
์์ ๊ฐ์ ๊ตฌ์กฐ๋ ํ์ดํ์ฒ๋ผ ๋์ํ์ง๋ง, ์๋ฐฉํฅ ํต์ ์ด ๊ธฐ๋ณธ์ ๋๋ค.
๊ธฐ๋ณธ PIPE๋ ๋จ๋ฐฉํฅ์ด์ง๋ง,
์๋ฐฉํฅ์ด ํ์ํ๋ค๋ฉด ๋ค์ 2๊ฐ์ง ๋ฐฉ๋ฒ ์ค ํ๋๋ฅผ ์จ์ผ ํด์:
์์ผ์ ํ๋ก์ธ์ค ๊ฐ ํต์ (IPC) ๋๋ ๋คํธ์ํฌ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ์๋ฐฉํฅ ํต์ ์ธํฐํ์ด์ค์ ๋๋ค.
์ข ๋ฅ | ์ฉ๋ | ์ค๋ช |
---|---|---|
๋คํธ์ํฌ ์์ผ | ์๊ฒฉ ํต์ | TCP/UDP๋ฅผ ์ด์ฉํ IP ๊ธฐ๋ฐ ํต์ |
์ ๋์ค ๋๋ฉ์ธ ์์ผ | ๋ก์ปฌ ํต์ | ๊ฐ์ ๋จธ์ ๋ด์ ํ๋ก์ธ์ค ๊ฐ ํต์ |
์์ผ ์ข ๋ฅ | ํ๋กํ ์ฝ | ์ค๋ช |
---|---|---|
AF_INET | TCP/UDP | IPv4 ๋คํธ์ํฌ ํต์ |
AF_INET6 | TCP/UDP | IPv6 ๋คํธ์ํฌ ํต์ |
AF_UNIX | local | ์ ๋์ค ๋๋ฉ์ธ ์์ผ (๊ฐ์ ๋จธ์ ๋ด ํ๋ก์ธ์ค ๊ฐ ํต์ ) |
AF_NETLINK | ์ปค๋ โ ์ฌ์ฉ์ ๊ณต๊ฐ | ์ฃผ๋ก ๋ฆฌ๋ ์ค ์ปค๋๊ณผ ์ฌ์ฉ์ ๊ณต๊ฐ ๊ฐ ๋ฉ์์ง ์ ๋ฌ |
AF_PACKET | ์ ์์ค ํจํท ์ ๊ทผ | ๋คํธ์ํฌ ์ธํฐํ์ด์ค ์์ค์ ํจํท ํต์ |
C, Python, Go, Java ๋ฑ ๋๋ถ๋ถ์ ์ธ์ด์์ ๋ฆฌ๋ ์ค ์์ผ API๋ฅผ ์ฌ์ฉํ ์ ์์ด์!
// C์์ ์์ผ ์์ฑ ์์
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
# Python์์ TCP ํด๋ผ์ด์ธํธ ์์
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("127.0.0.1", 8080))
๋ฆฌ๋
์ค๋ ์ด์ ๊ฐ์ ์์ผ์ ์์คํ
์ฝ๋ก ๊ด๋ฆฌํ๋ฉฐ, /proc
์์คํ
์์๋ ์์ผ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
AF_UNIX
, AF_LOCAL
๋ก ์ ์/tmp/mysocket
๊ฐ์ ์ค์ ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํด์ ํ๋ก์ธ์ค ๊ฐ ํต์ ๊ฐ๋ฅsocketpair()
๋ก ์๋ฐฉํฅ ํ์ดํ ๋์ฒด ๊ฐ๋ฅint fds[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
// fds[0], fds[1] โ ์๋ก ์ฝ๊ณ ์ฐ๊ธฐ ๊ฐ๋ฅ
๋ฆฌ๋ ์ค๋ ๋คํธ์ํฌ๋ ๋ก์ปฌ์ด๋ , ๋ค์ํ ์ข ๋ฅ์ ์์ผ ํต์ ์ ์๋ฒฝํ๊ฒ ์ง์ํฉ๋๋ค.
ํ์ดํ๋ณด๋ค ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ IPC ์๋จ์ผ๋ก ์์ฃผ ์ฌ์ฉ๋ผ์!
์ถ์ฒ : https://heeonii.tistory.com/13
msgtype
์ด๋ผ๋ ID ๊ฐ์ ๊ฐ์ง๊ณ ์์ด, ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์์ด์.์ ์ถ๋ ฅ ๋ฐฉ์์ผ๋ก๋ ์ต๋ช PIPE์ ๋์ผํ์ง๋ง, ์ปค๋์์ ๊ด๋ฆฌํ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ PIPE ์ ๋๋ค. ๊ตฌ์กฐ์ฒด ๊ธฐ๋ฐ์ผ๋ก ํต์ ์ ํฉ๋๋ค.
msgget()
, msgsnd()
, msgrcv()
, msgctl()
๋ฑ์ ์์คํ
์ฝ์ ํตํด ๋ฉ์์ง ํ๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํฉ๋๋ค.msgsnd()
๊ฐ ๋ธ๋กํน๋ฉ๋๋ค.ํญ๋ชฉ | ๋ด์ฉ |
---|---|
ํต์ ๋ฐฉํฅ | ๋จ๋ฐฉํฅ (์ผ๋ฐ์ ์ผ๋ก) |
๋ฐ์ดํฐ ๋จ์ | ๊ตฌ์กฐ์ฒด ๊ธฐ๋ฐ ๋ฉ์์ง |
๊ด๋ฆฌ ์ฃผ์ฒด | ์ปค๋ |
ํน์ง | msgtype ๊ธฐ๋ฐ์ผ๋ก ๋ค์ํ ๋ฐ์ดํฐ ๋ถ๊ธฐ ์ฒ๋ฆฌ ๊ฐ๋ฅ |
=
mmap()
์์คํ
์ฝ์ ์ด์ฉํด์ ํ์ผ์ ํน์ ๊ฐ์ ์ฃผ์ ์์ญ์ ๋งตํํฉ๋๋ค.execve()
๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ๋จ)MAP_SHARED
)์ ๊ฐ์ธ ๋ชจ๋(MAP_PRIVATE
)๋ฅผ ์ ํํ ์ ์์ด์.ํญ๋ชฉ | ๋ด์ฉ |
---|---|
ํต์ ๋ฐฉํฅ | ์๋ฐฉํฅ (MAP_SHARED ์ฌ์ฉ ์) |
๋ฐ์ดํฐ ๋จ์ | ํ์ผ ๊ธฐ๋ฐ |
๊ด๋ฆฌ ์ฃผ์ฒด | ์ปค๋ (ํ์ผ ์์คํ + ๋ฉ๋ชจ๋ฆฌ ๋งคํ) |
ํน์ง | ๋์ฉ๋ ๋ฐ์ดํฐ ๊ณต์ ์ ์ ํฉ, ํ์ผ ๊ธฐ๋ฐ |
์ธ๋งํฌ์ด๋ ๋ฆฌ๋ ์ค์์ ํ๋ก์ธ์ค ๊ฐ ๋๊ธฐํ๋ฅผ ์ํด ์ฌ์ฉ๋๋ IPC ๋ฉ์ปค๋์ฆ์ ๋๋ค. ํนํ, ๊ณต์ ์์์ ๋ํ ์ ๊ทผ์ ์ ์ดํ์ฌ ๋์์ฑ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
๋ฆฌ๋ ์ค์์๋ ๋ ๊ฐ์ง ์ ํ์ ์ธ๋งํฌ์ด๋ฅผ ์ง์ํฉ๋๋ค:
semget()
, semop()
, semctl()
๋ฑ์ ์์คํ
์ฝ์ ์ฌ์ฉํฉ๋๋ค.sem_init()
, sem_wait()
, sem_post()
, sem_destroy()
๋ฑ์ ์ฌ์ฉํ๋ฉฐ, ์ฃผ๋ก ์ค๋ ๋ ๊ฐ ๋๊ธฐํ์ ํ์ฉ๋ฉ๋๋ค.sem_open()
, sem_close()
, sem_unlink()
๋ฑ์ ์ฌ์ฉํ๋ฉฐ, ํ๋ก์ธ์ค ๊ฐ ๋๊ธฐํ์ ์ ํฉํฉ๋๋ค.#include <semaphore.h>
#include <pthread.h>
sem_t sem;
void* thread_func(void* arg) {
sem_wait(&sem);
// ์๊ณ ์์ญ
sem_post(&sem);
return NULL;
}
int main() {
sem_init(&sem, 0, 1);
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func, NULL);
pthread_create(&t2, NULL, thread_func, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sem);
return 0;
}
์ด ์์ ๋ ๋ ๊ฐ์ ์ค๋ ๋๊ฐ ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์๊ณ ์์ญ์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๋ ๋ชจ์ต์ ๋ณด์ฌ์ค๋๋ค.
RPC(Remote Procedure Call)๋ ๋ค๋ฅธ ์ฃผ์ ๊ณต๊ฐ์ ์๋ ํ๋ก์์ ๋ ํจ์๋ฅผ ํธ์ถํ ์ ์๊ฒ ํด์ฃผ๋ ํต์ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ์ด๋ฅผ ํตํด ๋ถ์ฐ ์์คํ ์์ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
๋ฆฌ๋ ์ค์์๋ ๋ค์ํ RPC ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค:
rpcgen
๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๊ณ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.example.x
):program EXAMPLE_PROG {
version EXAMPLE_VERS {
int add(int, int) = 1;
} = 1;
} = 0x20000001;
rpcgen example.x
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋ฆฌ๋ ์ค์์ RPC๋ฅผ ๊ตฌํํ์ฌ ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ์ํํ ์ ์์ต๋๋ค.
IPC ์ข ๋ฅ | PIPE | Named PIPE | Message Queue | Shared Memory | Memory Map | Socket | Semaphore | RPC |
---|---|---|---|---|---|---|---|---|
์ฉ๋ | ๋ถ๋ชจ ์์ ๊ฐ ๋จ๋ฐฉํฅ ํต์ | ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋จ๋ฐฉํฅ ํต์ | ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋จ๋ฐฉํฅ ํต์ | ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์๋ฐฉํฅ ํต์ | ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์๋ฐฉํฅ ํต์ | ๋ค๋ฅธ ์์คํ ๊ฐ ์๋ฐฉํฅ ํต์ | ๊ณต์ ์์ ์ ๊ทผ ์ ์ด ๋ฐ ๋๊ธฐํ | ๋ค๋ฅธ ์์คํ ํจ์ ์๊ฒฉ ํธ์ถ |
๊ณต์ ๋งค๊ฐ์ฒด | ํ์ผ | ํ์ผ | ๋ฉ๋ชจ๋ฆฌ | ๋ฉ๋ชจ๋ฆฌ | ํ์ผ + ๋ฉ๋ชจ๋ฆฌ | ์์ผ | ๋ฉ๋ชจ๋ฆฌ (์นด์ดํฐ ๊ธฐ๋ฐ) | ๋คํธ์ํฌ (TCP/IP, gRPC ๋ฑ) |
ํต์ ๋จ์ | stream | stream | ๊ตฌ์กฐ์ฒด | ๊ตฌ์กฐ์ฒด | ํ์ด์ง | stream | ์ ์ (์นด์ดํฐ, ํ๋๊ทธ) | ํจ์ ํธ์ถ (์์ฒญ/์๋ต ๋ฉ์์ง) |
ํต์ ๋ฐฉํฅ | ๋จ๋ฐฉํฅ | ๋จ๋ฐฉํฅ | ๋จ๋ฐฉํฅ | ์๋ฐฉํฅ | ์๋ฐฉํฅ | ์๋ฐฉํฅ | ์ ์ด ์ค์ฌ (๋ฐ์ดํฐ ์ ๋ฌ X) | ์๋ฐฉํฅ |
์ผ๋จ, ์ธ๋งํฌ์ด๋ IPC ๋ฐฉ์์ด ์๋ ์๋ ์๋ค๋ ๋ ผ์์ฌํญ์ด ๋์๋ค.
์ด์์ฒด์ ์์ ๋์์ ํ๋ ์ด์์ ํ๋ก์ธ์ค๊ฐ ์์์ ์ ๊ทผํ๋ ค ํ ๋, ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์์๋ก, ์ฐ๋ถํฌ์์ ์ฌ์ฉํ๋ APT ํจํค์ง ์์คํ ์ด ์์ด์:
apt
๋ช
๋ น์ด ๋์์ ์คํ๋๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์์ด ๋ฐ์ํ ์ ์์apt
๋ง ์คํ๋๋๋ก ๊ฐ์ ํฉ๋๋ค์ด๋ฌํ ๋ฉ์ปค๋์ฆ์ ์ฐ๋ฆฌ๋ ๋ฐฐํ์ ์ ์ด(Exclusive Control) ๋๋ ์ํธ ๋ฐฐ์ (Mutual Exclusion) ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
inc.sh
#!/bin/bash
TMP=$(cat count)
echo $((TMP + 1)) > count
count
ํ์ผ์ ์ฝ๊ณ ๊ฐ์ 1์ ๋ํฉ๋๋ค.A ํ๋ก์ธ์ค๊ฐ count ํ์ผ์์ ์ฝ์ โ ๊ฐ 0
B ํ๋ก์ธ์ค๋ count ํ์ผ์์ ์ฝ์ โ ๊ฐ 0
A๊ฐ count ํ์ผ์ 1 ์
B๋ count ํ์ผ์ 1 ์
โ ์ต์ข
๊ฒฐ๊ณผ๋ '1' (๋ ๋ค 1์ฉ ๋ํ์ง๋ง ์ค์ ์ฆ๊ฐ๋ 1)
์ด์ฒ๋ผ ํ์ผ ์ ์ถ๋ ฅ์ด ์ํ ๋ฏนํ์ง ์์์ ์ค๊ฐ์ ๋ผ์ด๋๋ ๊ฒฝ์ฐ๊ฐ ์๊น๋๋ค.
์ํ ๋ฏน(Atomic)์ด๋ ๋ง์ ์์์ฒ๋ผ ์ชผ๊ฐค ์ ์๋ ๋จ์์ ๋์์ด๋ผ๋ ๋ป์ด์์.
์ฆ, ์ค๊ฐ์ ๋๊ธฐ๊ฑฐ๋ ๋ค๋ฅธ ์์ ์ด ๋ผ์ด๋ค ์ ์๋ ์ฐ์ฐ์ ๋งํด์.
๐ฆ ๋น์ ํด๋ณผ๊ฒ์
๊ทธ๋ฐ๋ฐ ์ค๊ฐ์ ๋ค๋ฅธ ์ฌ๋์ด ๋ผ์ด๋ค ์ ์๋ค๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ๊ฒ ์ฃ :
A๊ฐ ๋ฌธ์ ์ด์๋๋ฐ B๊ฐ ๋จผ์ ๋ค์ด์๋ฒ๋ฆผ
โ A, B ๋ ๋ค ๋ค์ด๊ฐ๊ฒ ๋จ โ ์ถฉ๋ ๋ฐ์
๐ป ๊ทธ๋ผ ํ์ผ ์ ์ถ๋ ฅ์์ ์ ๋ฌธ์ ๊ฐ ๋๋์?
์, inc.sh
์์๋ฅผ ๋ค์ ๋ณด๋ฉด:
TMP=$(cat count) # 1๏ธโฃ ํ์ผ ์ฝ๊ธฐ
echo $((TMP + 1)) > count # 2๏ธโฃ 1 ๋ํด์ ๋ค์ ์ฐ๊ธฐ
์ด ์์ ์ ๊ฒ๋ณด๊ธฐ์ ํ๋์ฒ๋ผ ๋ณด์ด์ง๋ง, ๋ด๋ถ์ ์ผ๋ก๋ ๋ ๊ฐ์ ๋ ๋ฆฝ๋ ์์ ์ด์์.
์ฆ, ์ฝ๊ณ (cat) โ ๊ณ์ฐ โ ์ฐ๊ณ (echo) ์ด 3๋จ๊ณ๊ฐ ํ๋์ ์ํ ๋ฏน ์์ ์ด ์๋ ๊ฑฐ์์.
๊ทธ๋์ ์ค๊ฐ์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ๋ผ์ด๋ค ์ ์์ต๋๋ค!
๐งช ์ค์ ๋ฌธ์ ์ํฉ
# ๋ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๋์์ ์คํ๋ ๋
A: cat count # count = 0 ์ฝ์
B: cat count # count = 0 ์ฝ์
A: echo 1 > count
B: echo 1 > count
๐ฅ ์ค์ ๋ก๋ ๋ ๋ฒ ์ฆ๊ฐํ์ด์ผ ํ๋๋ฐ,
โ ๊ฒฐ๊ณผ๋1
๋ง ๋ฐ์๋จ (B๊ฐ A๋ฅผ ๋ฎ์ด์)
ํ์ผ ์ ์ถ๋ ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก "์ํ ๋ฏนํ์ง ์๋ค"
โ ์ฆ, ์ค๊ฐ์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ๋ผ์ด๋ค ์ ์์ด์ ์ถฉ๋์ด ์๊ธธ ์ ์์
โ ๊ทธ๋์flock
,semaphore
,mutex
๊ฐ์ ๋ฝ ๋๊ตฌ๋ก ๋ณดํธํด์ผ ํจ
inc-wrong-lock.sh
#!/bin/bash
while; do
if [ ! -e lock ]; then # 1) ๋ฝ ์๋ค?
break # 2) ๋ค์ด๊ฐ์!
fi
done
touch lock # 3) ๋ฝ ๊ฑธ๊ธฐ (๋ฆ์์ด์!)
TMP=$(cat count)
echo $((TMP + 1)) > count
rm -f lock
lock
ํ์ผ ์กด์ฌ ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํ ๋ค ์์ฑํ๋ ๋ฐฉ์touch lock
์ ๊น์ง ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ๋ผ์ด๋ค ์ ์์์์ | A ํ๋ก์ธ์ค | B ํ๋ก์ธ์ค |
---|---|---|
1 | lock ํ์ผ ์กด์ฌ ์ฌ๋ถ ํ์ธ โ ์์ | lock ํ์ผ ์กด์ฌ ์ฌ๋ถ ํ์ธ โ ์์ |
2 | "์ข์, ๋ค์ด๊ฐ๋ค!" | "์ข์, ๋๋ ๋ค์ด๊ฐ๋ค!" |
3 | touch lock | touch lock |
4 | count ์ฝ๊ณ 1 ๋ํจ | count ์ฝ๊ณ 1 ๋ํจ |
5 | ๊ฐ์ ๊ฐ์ count์ ์ | ๊ฐ์ ๊ฐ์ count์ ์ |
๊ฒฐ๊ตญ ๋ ์ค ํ๋์ ๊ฒฐ๊ณผ๋ง ๋ฐ์๋๊ณ , ๋๋จธ์ง๋ ๋ฎ์ด์ฐ๊ธฐ ๋นํจ!
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํผํ๋ ค๋ฉด count ๊ฐ์ ์ฝ์ด์ 1์ ๋ํ๊ณ ๊ทธ ๊ฐ์ count ํ์ผ์ ๋ค์ ์ฐ๋ ์ฒ๋ฆฌ๊ฐ ํ ๋ฒ์ ํ๋์ inc.sh ํ๋ก๊ทธ๋จ์์๋ง ์คํ๋๋๋ก ํด์ผ ํฉ๋๋ค.
์ด๊ฑธ ์ค์ ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ์ํธ ๋ฐฐ์ ์ ๋๋ค
flock
์ฌ์ฉ ์์flock
์ ์ด์ฉํ inc-lock.sh
#!/bin/bash
flock lock ./inc.sh
flock
๋ช
๋ น์ ํ์ผ์ ๋ฝ์ ์ค์ ํด์ ์ค๋ณต ์คํ์ ๋ง์์ค์ฉ์ด | ์๋ฏธ |
---|---|
ํฌ๋ฆฌํฐ์ปฌ ์น์ (์๊ณ๊ตฌ์ญ) | ๋์์ ์คํ๋๋ฉด ์ ๋๋ ์ฝ๋ ๊ตฌ๊ฐ |
์ํ ๋ฏน ์ฒ๋ฆฌ | ์ธ๋ถ์์ ๋ดค์ ๋ ํ๋์ ์ฒ๋ฆฌ์ฒ๋ผ ๋ณด์ด๋ ์ฐ์ฐ |
File Lock | ํน์ ํ์ผ์ ๋ฝ์ ๊ฑธ์ด ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ ๊ทผ์ ์ ์ด |
๋ฐฉ์ | ๋ฆฌ๋ ์ค ์ง์ ์ฌ๋ถ | ํน์ง |
---|---|---|
flock() | โ ์ง์ | ๊ฐ์ฅ ๊ฐ๋จํ ํ์ผ ๊ธฐ๋ฐ ๋ฝ |
fcntl() | โ ์ง์ | ์ข ๋ ์ ๋ฐํ ๋ฝ ์ ์ด ๊ฐ๋ฅ |
semaphore | โ ์ง์ | ๋ฉ๋ชจ๋ฆฌ ๋๊ธฐํ ๊ธฐ๋ฐ ๋ฝ |
pthread_mutex | โ (์ค๋ ๋ ์ ์ฉ) | ์ค๋ ๋ ๊ฐ ๋ฝ์ ์ํ ๊ตฌ์กฐ์ฒด |
๋ฆฌ๋ ์ค์์๋
flock
๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ํ ์์ ์ "ํ ๋ฒ์ ํ๋"๋ง ์ฒ๋ฆฌ๋๋๋ก ๋ฐฐํ์ ์ ์ด๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ฐ๋ฆฌ๋ flock()
, fcntl()
, pthread_mutex_lock()
๋ฑ์ ์ฌ์ฉํด ํ์ผ์ด๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฝ์ผ๋ก ๋ณดํธํฉ๋๋ค. ํ์ง๋ง ์ด๋ฌํ ํจ์๋ค ๋ด๋ถ์ ์ผ๋ก๋ CPU๊ฐ ์ ๊ณตํ๋ ๋ฝ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ฆ, ์ง์ง ๋ฝ์ ๊ธฐ๊ณ์ด ์์ค์์ ๊ตฌํ๋๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ๊ณ ๊ธ API๋ ๊ทธ ์์ ๋ง๋ค์ด์ง ์ถ์ํ ๊ณ์ธต์ผ ๋ฟ์ด์์.
์ฑ ์์๋ ๊ฐ์์ ์ด์ ๋ธ๋ฆฌ ์ธ์ด๋ฅผ ํตํด ๊ฐ๋จํ ๋ฝ ๋ฉ์ปค๋์ฆ์ ์ค๋ช ํฉ๋๋ค. ์ด ์์๋ฅผ ํตํด ์ํ ๋ฏน(atomic)ํ์ง ์์ผ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ์๊ธฐ๋์ง ๋ณด์ฌ์ค๋๋ค.
start:
load r0, mem ; mem์์ ๊ฐ์ r0์ ๋ก๋
test r0 ; r0์ด 0์ธ์ง ํ์ธ
jmpz enter ; 0์ด๋ฉด (lock ์ ๊ฑธ๋ฆผ) โ enter
jmp start ; ๊ทธ๋ ์ง ์์ผ๋ฉด โ ๋ค์ ์์
enter:
store mem, 1 ; lock ๊ฑธ๊ธฐ
<ํฌ๋ฆฌํฐ์ปฌ ์น์
์คํ>
store mem, 0 ; lock ํด์
์ด ๋ฐฉ์์
mem
์ด 0์ธ์ง ์ฝ๊ณ (lock ์ํ ํ์ธ), 1๋ก ๋ฐ๊พธ๊ณ (lock ์ค์ ), ํฌ๋ฆฌํฐ์ปฌ ์น์ ์คํ ํ 0์ผ๋ก ๋๋ฆฌ๋ ๊ตฌ์กฐ์ ๋๋ค.
์ ์ฝ๋๋ ๊ฒ๋ณด๊ธฐ์ ์ ๋์ํ ๊ฒ ๊ฐ์ง๋ง, ์ค์ ๋ก๋ ๋ฌธ์ ๊ฐ ๋ง์ต๋๋ค. ์์ผ๊น์?
load
โ test
โ store
๊ณผ์ ์ด ๋ถ๋ฆฌ๋์ด ์์ด์ ์ค๊ฐ์ ๋ผ์ด๋ค ์ ์์load
๋ฅผ ์คํํ๋ฉด, ๋ ๋ค mem = 0์ผ๋ก ํ๋จํ๊ณ ๋ฝ์ ํ๋ํ๋ ค๊ณ ํ ์ ์์๋๋ถ๋ถ์ ํ๋ CPU๋ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด "์ํ ๋ฏน ์ฐ์ฐ(Atomic Instruction)"์ ์ ๊ณตํฉ๋๋ค.
๋ํ์ ์ธ ์:
๋ช ๋ น์ด ์ด๋ฆ | ์ค๋ช |
---|---|
Test and Set | ๊ฐ์ ํ์ธํ ํ ๋ณ๊ฒฝ |
Compare and Swap | ์กฐ๊ฑด์ ๋ง์ผ๋ฉด ๊ฐ์ ๋ณ๊ฒฝ |
Exchange (XCHG ) | ๋ ๊ฐ์ ๊ตํ (๋ฝ ๊ตฌํ์ ์์ฃผ ์ฌ์ฉ) |
์ด๋ฌํ ๋ช ๋ น์ด๋ค์ ์ค๊ฐ์ ๋ผ์ด๋ค ์ ์๋๋ก CPU ์์ค์์ ์์ ํ ์์์ฑ ๋ณด์ฅ์ ์ ๊ณตํฉ๋๋ค.
Peterson's algorithm
์ busy waiting์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ๊ต์ก์ ๋ชฉ์ ์์ ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
์ง์ง ๋ฝ์ CPU ๋ด๋ถ์์ ์ํ ๋ฏน ๋ช ๋ น์ด๋ก ๊ตฌํ๋๋ฉฐ, ๊ณ ๊ธ ์ธ์ด์ ๋ฝ ํจ์๋ค์ ์ด ์ํ ๋ฏน ์ฐ์ฐ ์์ ๋ง๋ค์ด์ง ์ถ์ํ ๋๊ตฌ์ ๋๋ค.
ํ๋ CPU๋ ๋ฉํฐ์ฝ์ด๋ก ๊ตฌ์ฑ๋์ด ์์ด, ์ฌ๋ฌ ์์ ์ ๋์์ ์ํํ ์ ์๋ ํ๊ฒฝ์ด ๋ง๋ จ๋์ด ์์ต๋๋ค.
์ด๋ฅผ ํ์ฉํ๊ธฐ ์ํด ํ๋ก๊ทธ๋จ์ ๋ณ๋ ฌ๋ก ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ค์ ๋ ๊ฐ์ง์ ๋๋ค:
๋ฐฉ์ | ์ค๋ช |
---|---|
๋ฉํฐํ๋ก์ธ์ค (Multi-process) | ์ฌ๋ฌ ๊ฐ์ ๋ ๋ฆฝ์ ์ธ ํ๋ก๊ทธ๋จ์ ๋์์ ์คํ |
๋ฉํฐ์ค๋ ๋ (Multi-thread) | ํ๋์ ํ๋ก๊ทธ๋จ์ ์ฌ๋ฌ ํ๋ฆ(์ค๋ ๋)์ผ๋ก ๋๋์ด ์คํ |
fork()
๋๋ execve()
๋ฅผ ํตํด ๋
๋ฆฝ๋ ์์ ํ๋ก์ธ์ค ์์ฑ์: ์น ์๋ฒ๊ฐ ์์ฒญ๋ง๋ค ํ๋ก์ธ์ค๋ฅผ ์๋ก ์์ฑ
pthread_create()
๋ฑ์ผ๋ก ํ๋ก์ธ์ค ๋ด์ ์ฌ๋ฌ ํ๋ฆ ์์ฑ์: ํ๋์ ์๋ฒ ํ๋ก์ธ์ค๊ฐ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๋ ๋ ์ฌ์ฉ
๊ตฌ๋ถ | ์ฌ์ฉ์ ์ค๋ ๋ (User-level) | ์ปค๋ ์ค๋ ๋ (Kernel-level) |
---|---|---|
๊ด๋ฆฌ ์ฃผ์ฒด | ์ฌ์ฉ์ ๊ณต๊ฐ์ ์ค๋ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์ปค๋ |
์์ฑ/์ ํ ๋น์ฉ | ๋ฎ์ | ๋์ |
์ปค๋์์์ ์ธ์ | ๋ชจ๋ ์ฌ์ฉ์ ์ค๋ ๋ = ํ๋์ ์ปค๋ ์ค๋ ๋ | ๊ฐ๊ฐ ์ปค๋ ์ค๋ ๋๋ก ์ธ์ |
๋ณ๋ ฌ์ฑ | ์ ํ์ (ํ ๋ฒ์ ํ๋๋ง ์คํ) | ์ค์ ๋ณ๋ ฌ ์คํ ๊ฐ๋ฅ |
์์ | goroutine (Go), green thread | ๋ฆฌ๋ ์ค ์ค๋ ๋, Java thread (OS ์ฐ๋๋จ) |
ps aux
์์ [kthreadd]
, [rcu_gp]
๋ฑ []
๋ก ๊ฐ์ธ์ง ์ด๋ฆ์ ์ปค๋ ์ค๋ ๋kthreadd
๊ฐ ๋ฃจํธ์ด๋ฉฐ, ๋ค์ํ ์ปค๋ ์ค๋ ๋๋ฅผ ์์์ผ๋ก ์์ฑํจ๋ฉํฐํ๋ก์ธ์ค๋ ๋ ๋ฆฝ์ ์ธ ์คํ ๋จ์, ๋ฉํฐ์ค๋ ๋๋ ํ๋์ ๊ณต๊ฐ ์์์์ ๋ณ๋ ฌ ํ๋ฆ์ด๋ฉฐ, ์ฌ์ฉ์ ์ค๋ ๋๋ ๊ฐ๋ณ์ง๋ง ๋ณ๋ ฌ์ฑ์ด ๋ฎ๊ณ , ์ปค๋ ์ค๋ ๋๋ ๋ฌด๊ฒ์ง๋ง ์ง์ง ๋ณ๋ ฌ ์คํ์ด ๊ฐ๋ฅํฉ๋๋ค.