λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
  • Dev Blog
CS/운영체제

[운영체제] IPC

by μœ μ§„μ˜ 2023. 4. 23.
패슀트캠퍼슀 운영체제 κ°•μ˜μ™€ μ‰½κ²Œ λ°°μš°λŠ” 운영체제 κ΅μž¬μ— λŒ€ν•œ TILμž…λ‹ˆλ‹€.

 

ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신(IPC)

ν”„λ‘œμ„ΈμŠ€ ν˜Ήμ€ μŠ€λ ˆλ“œλŠ” λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰λœλ‹€. λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰λœλ‹€λŠ” 것은 ν”„λ‘œμ„ΈμŠ€/μŠ€λ ˆλ“œλŠ” λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€/μŠ€λ ˆλ“œμ˜ 곡간을 μ ‘κ·Όν•  수 μ—†λ‹€. μ™œλƒν•˜λ©΄, λ‚΄ ν”„λ‘œμ„ΈμŠ€μ˜ λ°μ΄ν„°λ‚˜ μ½”λ“œλ₯Ό λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ λ°”κΏ€ 수 있게 ν•˜λŠ” 것은 μœ„ν—˜ν•œ 일이기 λ•Œλ¬Έμ΄λ‹€. ν˜„λŒ€μ˜ 컴퓨터 μ‹œμŠ€ν…œμ€ μ„±λŠ₯을 높이기 μœ„ν•΄ μ—¬λŸ¬ ν”„λ‘œμ„ΈμŠ€/μŠ€λ ˆλ“œλ₯Ό λ™μ‹œμ— μ‹€ν–‰ν•˜λŠ”λ° μ΄λ•Œ, ν”„λ‘œμ„ΈμŠ€/μŠ€λ ˆλ“œ κ°„ μƒνƒœ 확인 및 데이터 μ†‘μˆ˜μ‹ μ€ κΌ­ ν•„μš”ν•˜λ‹€.

 

λ”°λΌμ„œ, ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신 방법을 μ œκ³΅ν•˜λŠ”λ°, 이λ₯Ό Inter Process Communication(IPC)라고 ν•œλ‹€. λŒ€λΆ€λΆ„μ˜ IPC 기법은 컀널 곡간을 ν™œμš©ν•˜λŠ” 것이닀. μ™œλƒν•˜λ©΄, 컀널 곡간은 λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€κ°€ κ³΅μœ ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

IPC 기법 μ’…λ₯˜

  • 곡유 파일 μ‚¬μš©
  • 곡유 λ©”λͺ¨λ¦¬ μ‚¬μš©
  • Pipe
  • Message Queue
  • Signal
  • Socket

 

곡유 파일 μ‚¬μš©

μ €μž₯ 맀체에 μ•ˆμ— μžˆλŠ” 곡유 νŒŒμΌμ„ μ‚¬μš©ν•˜λŠ” 것이닀.

 

 

곡유 νŒŒμΌμ„ μ΄μš©ν•œ 톡신은 ν”„λ‘œμ„ΈμŠ€ 1μ—μ„œ μ „λ‹¬ν•˜κ³  싢은 λ‚΄μš©μ„ 곡유 νŒŒμΌμ— 적고 ν”„λ‘œμ„ΈμŠ€ 2κ°€ 곡유 νŒŒμΌμ— 적힌 λ‚΄μš©μ„ μ½λŠ” 단방ν–₯ 톡신이닀. ν•˜μ§€λ§Œ, 곡유 νŒŒμΌμ„ μ΄μš©ν•œ 톡신은 μ‹€μ‹œκ°„μœΌλ‘œ 톡신을 μ£Όκ³ λ°›λŠ” 것에 어렀움이 λ”°λ₯Έλ‹€. μ™œλƒν•˜λ©΄, ν”„λ‘œμ„ΈμŠ€ 2μ—μ„œ ν”„λ‘œμ„ΈμŠ€ 1이 곡유 νŒŒμΌμ— λ­”κ°€λ₯Ό μ μ—ˆλ‹€λŠ” 것을 확인할 μˆ˜κ°€ μ—†μœΌλ‹ˆ κ³„μ†ν•΄μ„œ 읽어야 ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. λ˜ν•œ, μ €μž₯ 맀체의 I/O μž‘μ—…μ— λŒ€ν•œ μ˜€λ²„ν—€λ“œκ°€ 크기 λ•Œλ¬Έμ— 효과적인 톡신 방법은 μ•„λ‹ˆλ‹€.

 

λ”°λΌμ„œ, 이후에 λ‚˜μ˜€λŠ” IPC 기법듀은 μ €μž₯ 맀체λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹ˆλΌ I/O μž‘μ—…μ— λŒ€ν•œ μ˜€λ²„ν—€λ“œκ°€ 적은 λ©”λͺ¨λ¦¬μ˜ 컀널 μ˜μ—­μ„ μ‚¬μš©ν•΄μ„œ ν†΅μ‹ ν•œλ‹€.

 

 

 

곡유 λ©”λͺ¨λ¦¬ μ‚¬μš©

곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 톡신은 shmget()μ΄λΌλŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•΄ λ©”λͺ¨λ¦¬μ˜ 컀널 μ˜μ—­μ— 곡유 λ©”λͺ¨λ¦¬λ₯Ό μœ„ν•œ 곡간을 λ§Œλ“€μ–΄ 놓고 shmat μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•΄ ν•΄λ‹Ή λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό 마치 λ³€μˆ˜μ²˜λŸΌ μ ‘κ·Όν•˜λŠ” 방식이닀. 곡유 λ©”λͺ¨λ¦¬μ˜ keyλ₯Ό 가지고, μ—¬λŸ¬ ν”„λ‘œμ„ΈμŠ€κ°€ μ ‘κ·Όν•  수 μžˆλ‹€. μ΄λ•Œ, 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 톡신은 단방ν–₯ 톡신이닀.

 

 

곡유 νŒŒμΌμ„ μ‚¬μš©ν•˜λŠ” ν†΅μ‹ μ˜ 단점 쀑 ν•˜λ‚˜μΈ I/O μž‘μ—…μ— λŒ€ν•œ μ˜€λ²„ν—€λ“œ λ¬Έμ œλŠ” 해결을 ν•˜μ˜€μ§€λ§Œ μ—¬μ „νžˆ μƒλŒ€λ°©μ΄ 데이터λ₯Ό μ–Έμ œ 보낼 지 λ°›λŠ” μͺ½μ—μ„œ λͺ¨λ₯Έλ‹€λŠ” 단점은 ν•΄κ²°ν•˜μ§€ λͺ»ν•˜μ˜€λ‹€. λ”°λΌμ„œ, 데이터λ₯Ό λ°›λŠ” μͺ½μ—μ„œ λ°˜λ³΅λ¬Έμ„ λ¬΄ν•œ μ‹€ν–‰ν•˜λ©΄μ„œ 곡유 λ©”λͺ¨λ¦¬λ₯Ό 확인해야 ν•˜λŠ”λ° 이것을 λ°”μœ λŒ€κΈ°(Busy Waiting)이라고 ν•œλ‹€.

 

μ‰½κ²Œ λ°°μš°λŠ” 운영체제 κ΅μž¬μ—μ„œλŠ” μ΄λ ‡κ²Œ λ°”μœ λŒ€κΈ° μƒνƒœλ₯Ό κ°€μ§€λŠ” 톡신을 λŒ€κΈ°κ°€ μ—†λŠ” 톡신(Non-Blocking Communication)이라고 ν•˜λŠ”λ° 이 뢀뢄이 ꡉμž₯히 ν—·κ°ˆλ¦΄ 수 μžˆλ‹€. μ™œλƒν•˜λ©΄, 논블둝킹은 λ°”μœ λŒ€κΈ° μƒνƒœλ₯Ό 가지지 μ•ŠλŠ” 것이기 λ•Œλ¬Έμ΄λ‹€. λ‚˜μ˜ 개인적인 μƒκ°μœΌλ‘œλŠ” λŒ€κΈ°κ°€ 있고 μ—†κ³ μ˜ 주체λ₯Ό 일반 ν”„λ‘œμ„ΈμŠ€κ°€ μ•„λ‹Œ 운영체제 ν”„λ‘œμ„ΈμŠ€λ‘œ λ°”κΎΈλ©΄ μ‰½κ²Œ 이해가 λœλ‹€.

 

μ‰½κ²Œ 말해, 곡유 νŒŒμΌμ΄λ‚˜ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ΄μš©ν•œ 톡신을 ν•˜κ³  μžˆλŠ” ν”„λ‘œμ„ΈμŠ€ μžμ²΄μ—μ„œ λ°”μœ λŒ€κΈ° μƒνƒœλ₯Ό κ°€μ§μœΌλ‘œμ¨ λΈ”λ‘œν‚Ήμ΄ λ˜λ―€λ‘œ 운영체제 ν”„λ‘œμ„ΈμŠ€μ—μ„œ ν•΄λ‹Ή ν”„λ‘œμ„ΈμŠ€λ₯Ό μœ„ν•œ λŒ€κΈ° μƒνƒœλ₯Ό 제곡 μ•ˆ 해도 λœλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ”°λΌμ„œ, 곡유 νŒŒμΌμ΄λ‚˜ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 톡신은 운영체제 μž…μž₯μ—μ„œλŠ” λŒ€κΈ°κ°€ μ—†λŠ” 톡신, 즉 비동기화 톡신이라고 ν•  수 μžˆλ‹€.

 

 

νŒŒμ΄ν”„(Pipe) 톡신

νŒŒμ΄ν”„λ₯Ό μ΄μš©ν•œ 톡신은 λ©”λͺ¨λ¦¬μ˜ 컀널 곡간에 λ§Œλ“€μ–΄μ§„ νŒŒμ΄ν”„λ₯Ό μ‚¬μš©ν•΄μ„œ 톡신이 이루어진닀. μš΄μ˜μ²΄μ œκ°€ μ œκ³΅ν•˜λŠ” 동기화 톡신 방식, 즉 λŒ€κΈ°κ°€ μžˆλŠ” 톡신이고 단방ν–₯ 톡신이닀. νŒŒμ΄ν”„λ‘œ μ–‘λ°©ν–₯ 톡신을 ν•˜λ €λ©΄ νŒŒμ΄ν”„ 2개λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. νŒŒμ΄ν”„λ₯Ό μ΄μš©ν•œ 톡신은 fork() μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•΄ μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§Œλ“€μ—ˆμ„ λ•Œ, λΆ€λͺ¨μ™€ μžμ‹ ν”„λ‘œμ„ΈμŠ€ κ°„μ˜ 톡신 방법이닀.

char* msg = "Hello Child Process!";
int main()
{
    char buf[255];
    int fd[2], pid, nbytes;
    if (pipe(fd) < 0) // pipe(fd)둜 νŒŒμ΄ν”„ 생성
    	exit(1);
    pid = fork(); // 이 ν•¨μˆ˜ μ‹€ν–‰ λ‹€μŒ μ½”λ“œλΆ€ν„° λΆ€λͺ¨/μžμ‹ ν”„λ‘œμ„ΈμŠ€λ‘œ λ‚˜λˆ„μ–΄μ§
    if (pid > 0) { // λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λŠ” pid에 μ‹€μ œ ν”„λ‘œμ„ΈμŠ€ IDκ°€ 듀어감
    	write(fd[1], msg, MSGSIZE); //fd[1]에 μ“°κΈ°.
        exit(0);
    }
    else { // μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” pid에 0이 듀어감
    	nbytes = read(fd[0], buf, MSGSIZE); // fd[0]으둜 읽기
        printf("%d %s\n", nbytes, buf);
        exit(0);
    }
    return 0;
 }

 

μœ„ μ½”λ“œλŠ” νŒŒμ΄ν”„λ₯Ό μ‚¬μš©ν•œ 톡신을 κ΅¬ν˜„ν•œ μ½”λ“œ μ˜ˆμ œμ΄λ‹€. μœ„ μ½”λ“œμ—μ„œλŠ” λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€μ˜ μ“°κΈ° λ™μž‘μ΄ λ¨Όμ € μΌμ–΄λ‚˜κΈ° λ•Œλ¬Έμ— μžμ‹ ν”„λ‘œμ„ΈμŠ€μ—μ„œ 읽을 λ•Œ λŒ€κΈ°κ°€ ν•„μš”ν•˜μ§€ μ•Šλ‹€. λ§Œμ•½, μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„μ— λŒ€ν•œ 읽기 연산을 μˆ˜ν–‰ν–ˆλŠ”λ° λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ 아직 νŒŒμ΄ν”„μ— λŒ€ν•΄ μ“°κΈ° 연산을 μˆ˜ν–‰ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” λŒ€κΈ° μƒνƒœκ°€ λœλ‹€. μ΄λŸ¬ν•œ λŒ€κΈ° μƒνƒœλŠ” λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„μ— μ“°κΈ° 연산을 μˆ˜ν–‰ν•˜λŠ” μˆœκ°„ μžλ™μœΌλ‘œ ν’€λ € 동기화가 이루어진닀. λ”°λΌμ„œ, μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” λ°”μœ λŒ€κΈ°λ₯Ό ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

 

 

λ©”μ‹œμ§€ 큐(Message Queue)

νŒŒμ΄ν”„ 톡신과 λ§ˆμ°¬κ°€μ§€λ‘œ λ©”λͺ¨λ¦¬μ˜ 컀널 곡간에 큐 자료ꡬ쑰λ₯Ό μ‚¬μš©ν•΄μ„œ λ§Œλ“  λ©”μ‹œμ§€ 큐λ₯Ό μ‚¬μš©ν•΄ 톡신이 이루어진닀. νŒŒμ΄ν”„ ν†΅μ‹ μ²˜λŸΌ λΆ€λͺ¨-μžμ‹ ν”„λ‘œμ„ΈμŠ€ κ°„μ˜ ν†΅μ‹ λ§Œμ„ μœ„ν•œ 것이 μ•„λ‹ˆλΌ μ–΄λŠ ν”„λ‘œμ„ΈμŠ€ 간에라도 데이터 μ†‘μˆ˜μ‹ μ΄ κ°€λŠ₯ν•œ 방식이닀. λ˜ν•œ, νŒŒμ΄ν”„ ν†΅μ‹ μ²˜λŸΌ 단방ν–₯ 톡신이 μ•„λ‹Œ μ–‘λ°©ν–₯ 톡신이닀.

 

msgget(), msgsnd(), msgrcv()λΌλŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•΄ λ©”μ‹œμ§€ 큐λ₯Ό 생성, 데이터 솑신, μˆ˜μ‹ μ„ ν•  수 μžˆλ‹€.

 

 

 

λ‹€μŒμœΌλ‘œ λ‚˜μ˜¬ 두 가지 기법은 IPC용으둜 λ§Œλ“  기법은 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ, IPCμš©μœΌλ‘œλ„ μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμ— μ„€λͺ…ν•˜κ² λ‹€.

 

μ‹œκ·Έλ„(Signal)

μ‹œκ·Έλ„μ΄λž€ νŠΉμ • μ΄λ²€νŠΈκ°€ λ°œμƒλ˜μ—ˆμ„ λ•Œ μ‹ ν˜Έλ₯Ό λ³΄λ‚΄μ„œ μ•Œλ €μ£ΌλŠ” 것을 μ˜λ―Έν•œλ‹€. μ΄λŸ¬ν•œ μ‹œκ·Έλ„μ„ μ΄μš©ν•˜λ©΄ 컀널 λ˜λŠ” ν”„λ‘œμ„ΈμŠ€μ—μ„œ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€λ‘œ μ–΄λ–€ μ΄λ²€νŠΈκ°€ λ°œμƒλ˜μ—ˆλŠ”μ§€ μ•Œλ €μ€„ 수 있기 λ•Œλ¬Έμ— IPC에 μ‚¬μš©λ  수 μžˆλ‹€. 

 

μ‹œκ·Έλ„μ˜ λͺ¨λ“  μ’…λ₯˜λ₯Ό μ•Œκ³  μ‹ΆμœΌλ©΄ μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό 치면 λ³Ό 수 μžˆλ‹€.

kill -l


λŒ€λΆ€λΆ„μ˜ μ‹œκ·Έλ„μ€ μ»€λ„μ—μ„œ κΈ°λ³Έ λ™μž‘ μˆ˜ν–‰μ„ ν•œλ‹€. λ‹€μŒμ€ λͺ‡ 가지 κΈ°λ³Έ λ™μž‘ μ˜ˆμ‹œμ΄λ‹€.

 

  • SIGKILL: ν”„λ‘œμ„ΈμŠ€λ₯Ό μ£½μž„
  • SIGALARM: μ•ŒλžŒμ„ λ°œμƒμ‹œν‚΄
  • SIGSTOP: ν”„λ‘œμ„ΈμŠ€λ₯Ό 멈좀(Ctrl + z)
  • SIGCONT: λ©ˆμΆ°μ§„ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰μ‹œν‚΄
  • SIGINT: ν”„λ‘œμ„ΈμŠ€μ— μΈν„°λŸ½νŠΈλ₯Ό λ³΄λ‚΄μ„œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ£½μž„(Ctrl + c)
  • SIGSEGV: ν”„λ‘œμ„ΈμŠ€κ°€ λ‹€λ₯Έ λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μΉ¨λ²”ν–ˆμŒμ„ μ•Œλ¦Ό

 

ν”„λ‘œμ„ΈμŠ€ 톡신 κ΄€λ ¨ μ½”λ“œμ— κ΄€λ ¨ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό λ“±λ‘ν•˜λ©΄ ν•΄λ‹Ή μ‹œκ·Έλ„μ— λŒ€ν•œ κΈ°λ³Έ λ™μž‘μ„ λ¬΄μ‹œν•˜κ³  μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ— λ“±λ‘λœ λ™μž‘μ„ μˆ˜ν–‰ν•œλ‹€. 보톡은 μ»€λ„μ˜ κΈ°λ³Έ λ™μž‘μ΄ μ—†λŠ” SIGUSR1, SIGUSR2λΌλŠ” 두 개의 μ‹œκ·Έλ„μ„ μ‚¬μš©ν•΄μ„œ ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신을 ν•œλ‹€.

 

PCB에 ν•΄λ‹Ή ν”„λ‘œμ„ΈμŠ€κ°€ 처리 ν•΄μ•Όν•˜λŠ” μ‹œκ·Έλ„ κ΄€λ ¨ 정보λ₯Ό λ‹΄λŠ” 곡간이 μžˆμ–΄ ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신이 κ°€λŠ₯ν•˜λ‹€.

 

μ†ŒμΌ“(socket)

μ†ŒμΌ“μ€ 기본적으둜 ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ 같은 μ„œλ‘œ λ‹€λ₯Έ μ»΄ν“¨ν„°κ°„μ˜ λ„€νŠΈμ›Œν¬ 기반 톡신을 μœ„ν•œ κΈ°μˆ μ΄λ‹€. μ΄λŸ¬ν•œ μ†ŒμΌ“μ„ μ΄μš©ν•˜λ©΄ μ—¬λŸ¬ 컴퓨터에 μžˆλŠ” ν”„λ‘œμ„ΈμŠ€λΌλ¦¬λ„ 톡신을 ν•  수 μžˆλ‹€. λ˜ν•œ, 127.0.0.1 루프백 μ£Όμ†Œλ₯Ό μ‚¬μš©ν•˜λ©΄ 동일 μ»΄ν“¨ν„°μ˜ ν”„λ‘œμ„ΈμŠ€λΌλ¦¬λ„ 톡신할 수 μžˆλ‹€.

 

 

μ†ŒμΌ“μ€ ν”„λ‘œμ„ΈμŠ€ 동기화λ₯Ό μ§€μ›ν•˜λ―€λ‘œ 데이터λ₯Ό λ°›λŠ” μͺ½μ˜ ν”„λ‘œμ„ΈμŠ€κ°€ λ°”μœ λŒ€κΈ°λ₯Ό ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” 동기화 톡신 방식이고, μ†ŒμΌ“μ„ 1개만 μ‚¬μš©ν•΄λ„ μ–‘λ°©ν–₯ 톡신이 κ°€λŠ₯ν•˜λ‹€.

λŒ“κΈ€