Skip to content

Latest commit

ย 

History

History
986 lines (712 loc) ยท 33.3 KB

File metadata and controls

986 lines (712 loc) ยท 33.3 KB

Chapter10 ์‹œ์Šคํ…œ V์˜ ํ”„๋กœ์„ธ์Šค๊ฐ„ ํ†ต์‹ 

  • ์•ž์„œ ์‚ฌ์šฉํ•œ Read/write๋Š” ๋™๊ธฐํ™”๊ฐ€ ๋˜์ง€ ์•Š์Œ. ์˜ˆ๋ฅผ ๋“ค์–ด ์ •์ˆ˜, ์‹ค์ˆ˜, ๊ตฌ์กฐ์ฒด๋Š” ํฌ๊ธฐ๊ฐ€ ๋”ฑ ์ •ํ•ด์ ธ์žˆ์–ด์„œ ๊ตฌ๋ถ„ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š”๋ฐ ์ƒ๊ด€์ด ์—†์ง€๋งŒ, ๋ฌธ์ž์—ด ๊ฐ™์€ ๊ฒฝ์šฐ ๊ตฌ๋ถ„์ด ์•ˆ ๋˜๋‹ˆ ํ•œ ๋ฒˆ์— ์ฝ์–ด์˜ฌ ์ˆ˜๋ฐ–์— ์—†์Œ. ๋‹จ๋ฐฉํ–ฅ ์ฑ„๋„ ํ†ต์‹ ์ด๋ผ ๋ˆ„๊ฐ€ ์ฝ์–ด๊ฐ€๋Š”์ง€ ์ง€์ • ํ•ด์ฃผ์ง€ ๋ชปํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์–ฝํžˆ๊ฒŒ ๋œ๋‹ค.

  • ํ•˜์ง€๋งŒ IPC์—์„œ message ๋‚˜๋ˆ ์„œ ๋ณด๋‚ด๋ฉด ๋‚˜๋ˆ ์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ. ์–‘๋ฐฉํ–ฅ ์ฑ„๋„ ํ†ต์‹  ๊ฐ€๋Šฅํ•จ. ๋ฉ”์„ธ์ง€ํ๋Š” ์–ด๋А ๋ฉ”์„ธ์ง€๋ฅผ ๋ˆ„๊ฐ€ ๊ฐ€์ ธ๊ฐ€๋Š”์ง€ ๋ฉ”์„ธ์ง€ id๋กœ ๊ตฌ๋ถ„ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ.

  • IPC(Inter Processor Communication) ์„ค๋น„

    • ์ด๊ฑด ํŒŒ์ผ ์‹œ์Šคํ…œ์ด ์•„๋‹ˆ๊ณ  ํ•œ ๊ตฐ๋ฐ์—์„œ ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋А ๋””๋ ‰ํ† ๋ฆฌ๋“ ์ง€ ์ƒ๊ด€์—†์ด ์ด๋ฆ„์ด ๊ณ‚์น˜๋ฉด ์•ˆ ๋จ. ๊ทธ๋ž˜์„œ uniqueํ•œ

    • key

      • message_queue, semaphore, shared memory segment์— ๋Œ€ํ•œ identifier(ํŒŒ์ผ ์ด๋ฆ„์— ํ•ด๋‹น)
      • ์„œ๋กœ ๋‹ค๋ฅธ process๋“ค๋„ ๋™์ผ IPC ๊ฐ์ฒด๋Š” ๊ฐ™์€ key๊ฐ’์œผ๋กœ ์ ‘๊ทผ
      • ์‹œ์Šคํ…œ์—์„œ uniqueํ•œ key๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•จ. ==> ์ˆซ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์„ธ์ง€ํ ์ด๋ฆ„์œผ๋กœ ์ด์šฉ. ๊ณ‚์น˜๋ฉด ๊ฐ€์žฅ ๋นจ๋ฆฌ ๋งŒ๋“  ์‚ฌ๋žŒ์˜ ์†Œ์œ ๋กœ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์–ฝํžˆ๋‹ˆ๊นŒ key๊ฐ’ ์ƒ์„ฑ ์‹œ์Šคํ…œ ์ฝœ์„ ์‚ฌ์šฉํ•จ.
    • key๊ฐ’ ์ƒ์„ฑ

      #include <sys/ipc.h>
      
      key_t ftok(const char *path, int id);
      • ํ•ด๋‹น ํŒŒ์ผ์˜ st_dev, st_ino์™€ id๋กœ key๊ฐ’ ์ƒ์„ฑ
  • IPC ๊ฐ์ฒด ์ƒํƒœ ๊ตฌ์กฐ

    struct ipc_perm{
        uid_t cuid : ์ƒ์„ฑ์ž์˜ uid;
        gid_t cgid : ์ƒ์„ฑ์ž์˜ gid;
        uid_t uid : ์†Œ์œ ์ž์˜ uid;
        gid_t gid : ์†Œ์œ ์ž์˜ gid;
        mode_t mode : permission(execution์€ ์˜๋ฏธ ์—†์Œ)
    }
    
    • permission
      • ์ฝ๊ธฐ ๊ฐ€๋Šฅ : ํ ํ†ตํ•ด์„œ ๋ฉ”์„ธ์ง€ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
      • ์“ฐ๊ธฐ ๊ฐ€๋Šฅ : ํ ์ด์šฉํ•ด์„œ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Œ
      • ์‹คํ–‰ ๊ฐ€๋Šฅ : (์ฝ๊ธฐ/์“ฐ๊ธฐ๋งŒ ํ• ๊ฑฐ๋ผ ์‹คํ–‰์€ ์•ˆ ์”€. ์˜๋ฏธ ์—†์Œ)
  • IPC ์ •๋ณด ๊ฒ€์ƒ‰ ๋ฐ ์‚ญ์ œ

    • ipc ๊ด€๋ จ ์ •๋ณด ๊ฒ€์ƒ‰ $ ipcs

      ------ Message Queues --------
      key        msqid      owner      perms      used-bytes   messages    
      0x004007e0 1325301760 s122130    644        160          2           
      0x00f44f3c 1325957121 s16011068  644        0            0           
      0x00d5cb51 884738     s14011217  644        320          4           
      0x017b0674 1325596675 s13011093  644        80           1           
      0x00d5ca98 1325367300 s14011032  644        0            0           
      0x00d5cac8 1933317    s14011080  644        0            0           
      0x0001dcc9 557062     s122057    644        0            0           
      0x0001dd47 1325105159 s122183    644        720          9                     
      
      ------ Shared Memory Segments --------
      key        shmid      owner      perms      bytes      nattch     status      
      0x6c7f146d 0          root       600        3339312    3                       
      0x01130197 360449     root       600        1000       9                       
      0x00000000 131074     oracle     600        30040064   548                     
      0x00000000 163843     oracle     600        40399536128 274                     
      0x00000000 196612     oracle     600        104177664  274                     
      0x382b361c 229381     oracle     600        24576      274                     
      
      ------ Semaphore Arrays --------
      key        semid      owner      perms      nsems     
      0x7a7f146d 0          root       600        13        
      0x00000000 1966081    apache     600        1         
      0x00000000 1998850    apache     600        1         
      0x00000000 98307      apache     600        1         
      0x00000000 2031620    apache     600        1         
      0x00000000 2064389    apache     600        1         
      0x00000000 2097158    apache     600        1         
      0xd680bf9c 393223     oracle     600        140       
      
    • ipc ์‚ญ์ œ $ipcrm -m shmid or -q msqid or -s semid

Message Queue

  • Message passing

    • message queue๋ฅผ ํ†ตํ•œ message ์ „๋‹ฌ
      • msgget : queue ์ƒ์„ฑ
      • msgsnd : message ๋ณด๋‚ด๊ธฐ
      • msgrcv : message ๋ฐ›๊ธฐ
  • msgget ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•. ํŒŒ์ผ open ๊ธฐ๋Šฅ๊ณผ ์œ ์‚ฌ

      #include <sys/msg.h>
      
      int msgget(key_t key, int permflags);
    • key : message queue์˜ key ๊ฐ’

    • permflags = queue์— ๋Œ€ํ•œ access permission

      • IPC_CREAT
        • ํ•ด๋‹น queue๊ฐ€ ์—†์œผ๋ฉด, ์ƒ์„ฑํ•œ ํ›„ return; ์žˆ์œผ๋ฉด return;
        • ์ด flag๊ฐ€ ์„ค์ • ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š”, queue๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ return
      • IPC_EXCL
        • ํ•ด๋‹น queue๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋งŒ ์„ฑ๊ณต, ์•„๋‹ˆ๋ฉด -1 return
        • IPC_CREAT์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•ด์•ผํ•จ
    • return ๊ฐ’ : ์Œ์ˆ˜๊ฐ€ ์•„๋‹Œ queue identifier. ์ด๊ฑธ ์ž˜ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ

  • msgsnd ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/msg.h>
      
      int msgsnd(int mqid, const void *message, size_t size, int flags);
    • mqid : message queue identifier

    • message์˜ ์ฃผ์†Œ : ๋ณด๋‚ผ message๊ฐ€ ์ €์žฅ๋œ ์ฃผ์†Œ. cont void๋กœ ํƒ€์ž… ์ง€์ •๋œ๊ฑด ์ •์ˆ˜์ด๋“  ๋ฌธ์ž์—ด์ด๋“  ๊ตฌ์กฐ์ฒด ๋“ฑ๋“ฑ ์ด๋“  ํƒ€์ž… ์ƒ๊ด€์ด ์—†๊ธฐ ๋•Œ๋ฌธ.

    • size : long mtype ์ œ์™ธํ•œ message์˜ ํฌ๊ธฐ

    • flags

      • ํ•„์š”ํ•œ flag ์—†์œผ๋ฉด 0์œผ๋กœ ์„ค์ •
      • IPC_NOWAIT
        • send๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ์ฆ‰์‹œ return(queue๊ฐ€ ๊ฐ€๋“ ์ฐฌ ๊ฒฝ์šฐ). queue๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด blocking๋˜๊ณ  send๊ฐ€ ๋ถˆ๊ฐ€ํ•œ๋ฐ, ์ด๋•Œ blockํ•˜์ง€ ์•Š๊ณ  -1์„ ๋ฐ”๋กœ returnํ•˜๊ฒ ๋‹คํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ
        • flag๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด (0์ด๋ฉด), ์„ฑ๊ณต ์‹œ๊นŒ์ง€ blocking
    • return ๊ฐ’์€ 0 or -1

    • message์˜ ๊ตฌ์กฐ

      • long type์˜ ์ •์ˆ˜ ๊ฐ’์„ ๊ฐ–๋Š” mtype๊ณผ ์ž„์˜์˜ message์˜ ๋‚ด์šฉ์œผ๋กœ ๊ตฌ์„ฑ
      • message์˜ size๋Š” message ๋‚ด์šฉ์˜ ํฌ๊ธฐ๋งŒ
      • long mtype์—์„œ long ํƒ€์ž…์€ ๊ณ„์† ์œ ์ง€์‹œ์ผœ์•ผํ•จ. ๋ฐ”๊พธ๋ฉด ์•ˆ ๋˜๊ณ , ์Œ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉด ์•ˆ ๋จ. 0๋ณด๋‹ค ํฐ ์–‘์ˆ˜ ์•„๋ฌด๋‚˜ ๋“ค์–ด๊ฐ€๋ฉด ๋œ๋‹ค.
      struct mymsg{
          long mtype;				//message type(์–‘์˜ ์ •์ˆ˜)
          char mtext[SOMEVALUE];	//message ๋‚ด์šฉ
      }
    • msg queue ์ƒ์„ฑ ๋ฐ msg ๋ณด๋‚ด๊ธฐ ์˜ˆ์ œ

      struct q_entry{
          long mtype;
          int mnum;
      };
      
      int main(int argc, char **argv){
          int qid, i, in;
          struct q_entry msg;
          key_t key;
      
          key = ftok("keyfile", 1);
          qid = msgget(key, 0600|IPC_CREAT);
      
          for(i=0;i<3;i++){
              scanf("%d", &in);
              msg.mtype = i+1;
              msg.mnum = in;
              msgsnd(qid, &msg, sizeof(int), 0);
          }
          exit(0);
      }
      • fifo ๊ฐ™์€ ๊ฒฝ์šฐ ํ”„๋กœ๊ทธ๋žจ 2๊ฐœ๋ฅผ ๋™์‹œ์— open ์ˆœ์„œ ์ž˜ ๋งž์ถฐ์„œ ์‹คํ–‰ํ–ˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ์ด์œ ๋Š”,,,
      • blocking queue๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ ๋ณด๋‚ด๋†“์œผ๋ฉด ์žˆ์œผ๋ฉด ๋ฐ›๊ณ  ์•„๋‹ˆ๋ฉด ์•ˆ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•จ.
      • fifo๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„์ง fifo์— ์žˆ๋Š”๋ฐ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๋ฉด fifo ๋ฐ์ดํ„ฐ ๋‚จ์•„์žˆ์ง€ ์•Š๊ณ  ์‚ฌ๋ผ์ง
      • ๊ทผ๋ฐ message queue๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚จ์•„์žˆ์Œ. ๊ทธ๋ž˜์„œ ๊ฐ€๋Šฅ
  • msgrcv

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/msg.h>
      
      int msgrcv(int mqid, void *message, size_t size, long msg_type, int flags);
    • mqid : message queue identifier

    • message ์ฃผ์†Œ : ๋ฐ›์€ message๋ฅผ ์ €์žฅํ•  ์ €์žฅ ์žฅ์†Œ์˜ ์ฃผ์†Œ

    • size : long mtype ์ œ์™ธํ•œ, ์ค€๋น„๋œ ์ €์žฅ ์žฅ์†Œ์˜ ํฌ๊ธฐ

    • msg_type

      • 0 : queue์˜ ์ฒซ message. ๋ฉ”์„ธ์ง€ ํƒ€์ž… ์ƒ๊ด€์—†์ด ํ ์ œ์ผ ์•ž ๋ฉ”์„ธ์ง€๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐ›๊ฒ ๋‹ค.
      • _ > 0 : ํ•ด๋‹น ๊ฐ’์„ ๊ฐ–๋Š” ์ฒซ message. 1์ ์œผ๋ฉด ๋งจ ์•ž 1๋ฒˆ message, 100 ์ ์œผ๋ฉด ๋งจ ์•ž 100๋ฒˆ message ๊ณจ๋ผ์„œ ์ฝ๊ฒ ๋‹ค.
      • _ < 0 : mtype๊ฐ’์ด ์ ˆ๋Œ€๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฒƒ ์ค‘ ์ตœ์†Œ๊ฐ’์„ ๊ฐ–๋Š” ์ฒซ message. -5 ์ ์œผ๋ฉด 5๋ณด๋‹ค ์ž‘์€ ์•„๋ฌด ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›๊ฒ ๋‹ค.
    • flags

      • IPC_NOWAIT
        • ๋ฉ”์„ธ์ง€ ๋ฐ›์„ ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ blocking์ธ๋ฐ,,, ๋ฉ”์„ธ์ง€ ์•ˆ ์™€๋„ ์•ˆ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๊ฒ ๋‹ค ํ•˜๋ฉด ์‚ฌ์šฉ. ์—†์œผ๋ฉด -1 ๋ฐ”๋กœ return
        • receive๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ์ฆ‰์‹œ return(queue์— ํ•ด๋‹น msg๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ)
        • return ๊ฐ’์€ -1; errno = EAGAIN
        • flag๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด (๊ฐ’์ด 0์ด๋ฉด), ์„ฑ๊ณต ์‹œ๊นŒ์ง€ blocking
      • MSGNOERROR
        • message๊ฐ€ size๋ณด๋‹ค ๊ธธ๋ฉด ์ดˆ๊ณผ๋ถ„์„ ์ž๋ฅธ๋‹ค
        • ์ •์ˆ˜ 5๊ฐœ๊ฐ€ ์˜ฌ ๊ฑธ ์˜ˆ์ƒํ•˜์—ฌ 5๊ฐœ ๊ณต๊ฐ„๋งŒ ๋งŒ๋“ค์–ด๋†“์•˜๋Š”๋ฐ, ์ •์ˆ˜ 10๊ฐœ๋ฅผ ๋ฐ›์œผ๋ฉด ์›์น™์ ์œผ๋กœ ์‹คํŒจํ•˜๋ฉด์„œ -1์„ return ํ•˜๋Š”๋ฐ, ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋’ค์— 5๊ฐœ๋ฅผ ํฌ๊ธฐํ•˜๊ณ  ์•ž์— 5๊ฐœ๋งŒ ๋ฐ›๊ฒ ๋‹ค ์ด๋Ÿฐ ๊ฒฝ์šฐ flag ์„ค์ •
        • flag๊ฐ€ ์„ค์ • ๋˜์ง€ ์•Š์œผ๋ฉด size ์ดˆ๊ณผ ์‹œ error
    • return ๊ฐ’

      • receive ์„ฑ๊ณต ์‹œ ๋ฐ›์€ message์˜ ๊ธธ์ด
      • ์‹คํŒจ ์‹œ -1
      • access permission ๋•Œ๋ฌธ์— ์‹คํŒจํ•œ ๊ฒฝ์šฐ error = EACCESS
    • message ์†ก์ˆ˜์‹  ์˜ˆ

      • ์˜ˆ1
      struct q_entry{
          long mtype;
          int mnum;
      };
      
      int main(int argc, char **argv){
          int qid, i, in;
          struct q_entry msg;
          key_t key;
      
          key = ftok("keyfile", 1);
          qid = msgget(key, 0600|IPC_CREAT);
      
          for(i=0;i<3;i++){
              msgrcv(qid, &msg, sizeof(int), -3, 0);
              printf("%d\n", msg.mnum);
          }
          exit(0);
      }
      • ์•ž์— ๋ฉ”์„ธ์ง€ ํ ์ƒ์„ฑ ๋ฐ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐ ์ดํ›„, ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ์˜ˆ์ œ ์ดํ›„ ๋ฉ”์„ธ์ง€ ํ ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ํ™•์ธํ•œ ๊ฒฐ๊ณผ. 10,11,12 ์„ธ ๊ฐœ์˜ ์ˆซ์ž๋ฅผ ์ž…๋ ฅ๋ฐ›์•„์„œ 12๋ฐ”์ดํŠธ์— 3๊ฐœ์˜ QNUM์ด ์žˆ๋Š” ๊ฒƒ ํ™•์ธ -3์œผ๋กœ msg_type ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 1,2,3 id์˜ ์ˆซ์ž ์•„๋ฌด๊ฑฐ๋‚˜ ์„ธ ๋ฒˆ ์ˆ˜์‹ ํ•˜๋Š” ์ฝ”๋“œ๋ผ 3๊ฐœ์˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋‹ค ์ฝ์–ด์™”๊ณ , ๋น„์–ด์žˆ๋Š” ๋ฉ”์„ธ์ง€ ํ ์‚ญ์ œํ•œ ๊ณผ์ •
      sinjaeheoguiMBP:unix jaehyukshin$ ./example.out
      10
      11
      12
      sinjaeheoguiMBP:unix jaehyukshin$ ipcs -qo
      IPC status from <running system> as of Sat Nov 17 13:21:50 KST 2018
      T     ID     KEY        MODE       OWNER    GROUP CBYTES  QNUM
      Message Queues:
      q 131072 0xffffffff --rw------- jaehyukshin    staff     12      3
      
      sinjaeheoguiMBP:unix jaehyukshin$ ./example2.out
      10
      11
      12
      sinjaeheoguiMBP:unix jaehyukshin$ ipcs -qo
      IPC status from <running system> as of Sat Nov 17 13:22:02 KST 2018
      T     ID     KEY        MODE       OWNER    GROUP CBYTES  QNUM
      Message Queues:
      q 131072 0xffffffff --rw------- jaehyukshin    staff      0      0
      
      sinjaeheoguiMBP:unix jaehyukshin$ ipcrm -q 131072
      sinjaeheoguiMBP:unix jaehyukshin$ ipcs -qo
      IPC status from <running system> as of Sat Nov 17 13:22:18 KST 2018
      T     ID     KEY        MODE       OWNER    GROUP CBYTES  QNUM
      Message Queues:
      
      
      • ์˜ˆ2 ๋ฉ”์„ธ์ง€ ํ์— ์žˆ๋Š” 1,2,3 id์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์€ ํ›„์— ๋ฐ›์€ ๊ฐ’์— +8ํ•˜์—ฌ id 4๋กœ ๋‹ค์‹œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ„. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ๋ฉ”์‹œ์ง€ ํ์— ์žˆ๋Š” id 4์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ถœ๋ ฅํ•จ. flag์— 0 ๋ง๊ณ  IPC_NOWAIT ๋„ฃ์œผ๋ฉด block์„ ์•ˆ ํ•ด์„œ ๋ฉ”์„ธ์ง€ ์—†์œผ๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด์„œ while๋ฌธ์„ ๋น ์ ธ๋‚˜๊ฐ. ๊ทผ๋ฐ 0์„ ๋„ฃ์œผ๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค ์ฝ์€ ํ›„์—๋„ ๋ฉ”์‹œ์ง€๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ๊ณ„์† ๊ธฐ๋‹ค๋ฆผ. (์ฐจ์ด ์ฃผ์˜ํ•  ๊ฒƒ)
      struct q_entry{
          long mtype;
          int mnum;
      };
      
      int main(int argc, char **argv){
          int qid, i, in;
          struct q_entry msg;
          key_t key;
      
          key = ftok("keyfile", 1);
          qid = msgget(key, 0600|IPC_CREAT);
      
          if(qid == -1){
              perror("msgget");
              exit(0);
          }
      
          while(msgrcv(qid, &msg, sizeof(int), -3, IPC_NOWAIT) > 0){
              msg.mtype = 4;
              msg.mnum = msg.mnum + 8;
              printf("%d\n", msg.mnum);
              msgsnd(qid, &msg, sizeof(int), 0);
          }
      
          for(i=0;i<3;i++){
              msgrcv(qid, &msg, sizeof(int), 4, 0);
              printf("%dth this is it : %d\n", i, msg.mnum);
          }
          
          //๋ฉ”์„ธ์ง€ํ ๊ธฐ๋Šฅ ๋‹ค ์‚ฌ์šฉํ•˜๊ณ  ์‚ญ์ œํ•ด์ฃผ๋Š” ์‹œ์Šคํ…œ ์ฝœ ์‚ฌ์šฉ
          msgctl(qid, IPC_RMID, 0);
          
          exit(0);
      }
  • msgctl

    • Fifo vs msg queue ๊ฐ€์žฅ ํฐ ์ฐจ์ด

      • fifo๋Š” ์ „๋ถ€ ์ข…๋ฃŒ ์‹œ ์‚ฌ๋ผ์ง
      • msg queue๋Š” ์ „๋ถ€ ์ข…๋ฃŒ ์‹œ msg ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ์Œ
    • message queue ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด ๊ฐ™์€ ๊ฒฝ์šฐ๋„ ์–ผ๋งˆ๋‚˜ ๋‚˜๋ˆ ์„œ ๋ณด๋ƒˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Œ

    • Message queue์— ๋Œ€ํ•œ ์ •๋ณด ํš๋“. msgctl์€ ๋ฉ”์‹œ์ง€ ํ์™€ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

    • Message queue ์ œ๊ฑฐ ๊ธฐ๋Šฅ. message queue ๊ฐ™์€ ๊ฒฝ์šฐ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐฏ์ˆ˜๊ฐ€ ์ œํ•œ๋ผ์„œ ์‚ฌ์šฉํ•˜๊ณ  ์ง€์›Œ์•ผํ•จ. ์ผ์ผ์ด ์ง€์šฐ๊ธฐ๋„ ํ•˜๋Š”๋ฐ msgctl๋กœ ์ง€์›Œ์คŒ

      #include <sys/msg.h>
      
      int msgctl(int mqid, int command, struct msqid_ds *msq_stat);
    • mqid : message queue identifier

    • command

      • IPC_STAT : msg queue์˜ ์ƒํƒœ ์ •๋ณด ํ™•์ธ. stat ์ •๋ณด ์ €์žฅํ•  ๊ณต๊ฐ„์„ 3๋ฒˆ์งธ ์ธ์ž์— ์ ์–ด์ค˜์•ผํ•จ
      • IPC_RMID : msg queue ์‚ญ์ œ. 3๋ฒˆ์งธ ์ธ์ž ํ•„์š” ์—†๊ธฐ ๋•Œ๋ฌธ์— 0์œผ๋กœ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
    • msqid_ds์˜ ๊ตฌ์กฐ

      struct ipc_perm msg_perm;	//์†Œ์œ ๊ถŒ
      msgqnum_t msg_qnum;			//msg ์ˆ˜
      msglen_t msg_qbytes;		//bytes ์ˆ˜
      pid_t msg_lspid;			//last sender
      pid_t msg_lrpid;			//last receiver
      time_t msg_stime;			//last sending time
      time_t msg_rtime;			//last receipt time
      time_t msg_ctime;			//last s/r time
      

Semaphore

  • semaphore

    • p(sem) or wait(sem)

      if(sem > 0){
      	//์„ธ๋งˆํฌ ๊ฐ’ ํ•˜๋‚˜ ๋บŒ. ๊ทธ๋ฆฌ๊ณ  ๋ฐ”๋กœ return. no blocking
         	decrement sem by one;
      }
      else{
      	//์„ธ๋งˆํฌ 0๋ณด๋‹ค ํฐ ๊ฐ’์ด ๋  ๋•Œ๊นŒ์ง€ blocking.
          wait until sem becomes non-zero;
          then decrement;
      }
      //๊ทธ๋ƒฅ OS์—์„œ๋Š” ๋นผ๊ณ ๋‚˜์„œ blockํ–ˆ๋Š”๋ฐ, ์œ ๋‹‰์Šค๋Š” ๊นจ์–ด๋‚  ๋•Œ ๋ฐ”๋กœ ๋นผ์คŒ.
      //๊ฒฐ๋ก ์€ ๊ฐ™์€ ์ž‘์—…์ด๋‚˜ ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅธ ์ด์œ ๋Š”, unix์—์„œ ์„ธ๋งˆํฌ๋Š” ์Œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ. ๊ทธ๋ž˜์„œ 0๋ณด๋‹ค ์ปค์งˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๊นจ์–ด๋‚˜๋ฉด์„œ ๋นผ์ค€๋‹ค.
      
    • v(sem) or signal(sem)

      //์„ธ๋งˆํฌ ๊ฐ’์„ ํ•˜๋‚˜ ๋”ํ•จ
      increment sem by one;
      
      //ํ๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ. ํ๊ฐ€ ์•ˆ ๋น„์–ด์žˆ์œผ๋ฉด ์ฒซ๋ฒˆ์งธ block๋œ๊ฑธ ๋‹ค์‹œ ์‹คํ–‰.
      if(queue of waiting processes not empty)
      	restart first process in wait queue;
      
    • ์‚ฌ์šฉ ์˜ˆ

      • ์„ธ๋ชจํฌ ์„ค์ •ํ•  ๋•Œ ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •ํ•˜๋Š”๊ฒŒ ์ค‘์š”ํ•จ
      p(sem);					//wait
      something interesting;	//critical section
      v(sem);					//signal
      
  • semget ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/sem.h>
      #include <sys/types>
      #include <sys/ipc.h>
      
      int semget(key_t key, int nsems, int permflags);
    • key : semaphore ์ง‘ํ•ฉ ์ด๋ฆ„

    • nsems : semaphore ์ง‘ํ•ฉ ๋‚ด์˜ semaphore ์ˆ˜. ์ง‘ํ•ฉ์œผ๋กœ ํ•„์š”ํ•œ๋งŒํผ ์„ธ๋งˆํฌ ์ƒ์„ฑ ๊ฐ€๋Šฅ.

    • permflags : 0600, IPC_CREAT, IPC_EXCL โ€ฆ / ๋ฉ”์‹œ์ง€ ํ ๋งŒ๋“ค ๋•Œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•œ ์˜ต์…˜ ์˜๋ฏธ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

    • return ๊ฐ’ : semaphore ์ง‘ํ•ฉ identifier

    • ์„ธ๋งˆํฌ ์ง‘ํ•ฉ ๋ฐฐ์—ด์— ํ•œ๊บผ๋ฒˆ์— ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋…๋ฆฝ์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋ช‡ ๋ฒˆ index์˜ ์„ธ๋งˆํฌ๊ฐ€ ~ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

      • semid[0] : index0 : semval = 2
      • semid[1] : index1 : semval = 4
      • semid[2] : index2 : semval = 1
      • semid[3] : index3 : semval = 3
      • ==> ์ด๋ ‡๊ฒŒ ๋œ ๊ฒฝ์šฐ, nsems = 4 ๊ฐ€ ๋œ๋‹ค
    • ์ง‘ํ•ฉ ๋‚ด ๊ฐ semaphore์™€ ์—ฐ๊ด€๋œ ๊ฐ’

      • semval : semaphore ๊ฐ’ (semapahore ๊ฐ’์˜ ์ดˆ๊ธฐํ™” ํ•„์š”)
      • sempid : ์ตœ๊ทผ semaphore๋ฅผ access ํ•œ process id. ์ดˆ๊ธฐํ™”, wait, signal ๋“ฑ์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— ๋ณ€๊ฒฝํ•œ ์„ธ๋งˆํฌ ๊ฐ’
      • ์œ ๋‹‰์Šค ์„ธ๋งˆํฌ์—๋Š” ๋‘ ๊ฐœ์˜ ํ๊ฐ€ ์กด์žฌ. ๊ทผ๋ฐ ์œ ๋‹‰์Šค์—๋Š” ์Œ์ˆ˜๊ฐ’์„ ๊ฐ–์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ์— ๋ช‡ ๋ช…์ด ๊ธฐ๋‹ค๋ฆฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Œ. ๊ทธ๋ž˜์„œ ์ด๊ฑธ ์‚ฌ์šฉํ•˜์—ฌ ํ์— ๋ช‡ ๋ช…์ด ๊ธฐ๋‹ค๋ฆฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Œ
        • semncnt : semaphore ๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” process ์ˆ˜. 0์ผ ๋•Œ ๋„์ฐฉํ•ด์„œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒฝ์šฐ
        • semzcnt : semaphore ๊ฐ’์ด 0์ด ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” process ์ˆ˜. 0์ด ์•„๋‹ ๋•Œ ๋„์ฐฉํ•ด์„œ 0์ด ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒฝ์šฐ
  • semctl ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/sem.h>
      
      int semctl(int semid, int sem_num, int command, union semun arg);
    • semid : semaphore identifier

    • sem_num : ์ง‘ํ•ฉ ๋‚ด ํŠน์ • semaphore ์ง€์ •

    • command

      • IPC_STAT : ์ƒํƒœ ์ •๋ณด๋ฅผ arg.stat์— ์ €์žฅ. ์„ธ๋งˆํฌ์™€ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋„ค ๋ฒˆ์งธ ์ธ์ž์— ๋ช…์‹œํ•œ ๊ณณ์— ์ €์žฅ
      • IPC_RMID : semaphore ์ง‘ํ•ฉ ์‚ญ์ œ. ์‚ญ์ œ๋งŒ ํ•˜๋Š”๊ฑฐ๋ผ ๋„ค ๋ฒˆ์งธ ์ธ์ž ๊ฐ’์— 0์œผ๋กœ ์„ค์ •
    • command => ๋‹จ์ผ semaphore์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ธฐ๋Šฅ. (semctl return ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์คŒ)

      • GETVAL : semval ๊ฐ’ return
      • SETVAL : semavl ๊ฐ’์„ arg.val ๊ฐ’์œผ๋กœ ์ง€์ •
      • GETPID : sempid ๊ฐ’์„ return
      • GETNCNT : semncnt ๊ฐ’์„ return. ์ฒซ ๋ฒˆ์งธ ํ์—์„œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ˆซ์ž
      • GETZCNT : semzcnt ๊ฐ’์„ return. ๋‘ ๋ฒˆ์งธ ํ์—์„œ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ˆซ์ž
    • command => semaphore ์ง‘ํ•ฉ ์ „์ฒด์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ธฐ๋Šฅ. (semctl return ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์คŒ)

      • GETALL : ๋ชจ๋“  semval ๊ฐ’์„ arg.array์— ์ €์žฅ. ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ’ ํ•œ๊บผ๋ฒˆ์— ์˜ค๋‹ˆ๊นŒ return๊ฐ’ ์‚ฌ์šฉ ์•ˆ ํ•˜๊ณ , ์ €์žฅ ๊ณต๊ฐ„์˜ ์ฃผ์†Œ๋ฅผ ์•Œ๋ ค์ฃผ๋ฉด ๋œ๋‹ค.
      • SETALL : arg.array ๊ฐ’์œผ๋กœ ๋ชจ๋“  semval ๊ฐ’์„ ์ง€์ •. ์„ธ๋งˆํฌ ๊ฐ’์ด 10๊ฐœ๋ฉด 10๊ฐœ ๊ฐ’ ํ•œ๊บผ๋ฒˆ์— ๋‹ค ์„ค์ •
    • struct semun arg;

      union semun{
          int val;
          struct semid_ds *buf;
          unsigned short *array;
      };
      • struct์™€ union์˜ ์ฐจ์ด : ๊ตฌ์กฐ์ฒด๋Š” a,b,c ์ •๋ณด ํ•„์š”ํ•˜๋ฉด ๋‹ค ๋ฉค๋ฒ„๋กœ ๊ฐ€์ง€์ง€๋งŒ, union์€ a,b,c ์ •๋ณด ํ•„์š”ํ•˜๋ฉด ์–ด์ฉ”๋•Œ๋Š” a๋กœ ์“ฐ์ด๊ณ , ์–ด์ฉ”๋•Œ๋Š” b๋กœ ์“ฐ์ด๊ณ ,,, ์ด๋ ‡๊ฒŒ ํ•˜๋‚˜๋ฅผ ๊ณจ๋ผ์„œ ์‚ฌ์šฉํ•จ.
    • semaphore ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

      union semun{
          int val;
          struct semid_ds *buf;
          ushort *array;
      };
      
      key_t key;
      union semun arg;
      key = ftok("key", 3);
      semid = semget(key, 1, 0600|IPC_CREAT|IPC_EXCL);
      arg.val = 3;
      semctl(semid, 0, SETVAL, arg);
      • ์„ธ๋งˆํฌ ์žˆ์œผ๋ฉด ์•„์˜ˆ ๋งŒ๋“ค์ง€ ๋ง๊ณ , ์„ธ๋งˆํฌ ์—†์„ ๋•Œ๋งŒ ๋งŒ๋“ค๋ผ๋Š” ๋œป์ธ๋ฐ ์™œ ์ด ์˜ต์…˜์ด ํ•„์š”ํ•œ์ง€์— ๋Œ€ํ•ด ์ž˜ ์ƒ๊ฐํ•ด๋ณด๊ธฐ

      • ==> ์„ธ๋งˆํฌ์™€ ๊ณต์œ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ดˆ๊ธฐํ™”๊ฐ€ ํ•„์ˆ˜์ธ๋ฐ, ํ•œ๊บผ๋ฒˆ์— ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋“ค์ด ์ดˆ๊ธฐํ™”๋ฅผ ์‹œ๋„ํ•˜๋ฉด ์–ฝํžˆ๊ธฐ ๋•Œ๋ฌธ์— (ํ•œ ์„ธ๋งˆํฌ, ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—) ๋”ฑ ํ•œ ํ”„๋กœ์„ธ์Šค๋งŒ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ IPC_EXCL ์˜ต์…˜์„ ์‚ฌ์šฉํ•จ

    • semaphore ์ง‘ํ•ฉ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

      union semun{
          int val;
          struct semid_ds *buf;
          ushort *array;
      };
      
      int i;
      key_t key;
      union semun arg;	//์—ฌ๊ธฐ ์•ˆ์—๋Š” ํฌ์ธํ„ฐ๋ฐ–์— ์—†์œผ๋‹ˆ ์ด ๊ฐ’๋“ค์„ ๋˜ ๋ณ„๋„๋กœ ์ €์žฅํ•  ๋ณ€์ˆ˜ buf[3] ์ƒ์„ฑ
      ushort buf[3];
      
      semid = semget(key, 3, 0600|IPC_CREAT|IPC_EXCL);
      for(i=0;i<3;i++)
          buf[i] = i + 1;
      arg.array = buf;
      semctl(semid, 0, SETALL, arg);
  • semop ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/sem.h>
      
      int semop(int semid, struct sembuf *op_array, size_t num_ops);
    • semid : semaphore identifier

    • oparray : ์ˆ˜ํ–‰ํ•  ์—ฐ์‚ฐ ์ง€์ •

    • num_ops : op_array ๋‚ด์˜ sembuf์˜ ์ˆ˜. (์—ฌ๋Ÿฌ๊ฐœ์˜ semaphore์— ๋Œ€ํ•œ ์—ฐ์‚ฐ์„ ๋™์‹œ์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ)

    • sembuf์˜ ๊ตฌ์กฐ

      struct sembuf{
          unsigned short sem_num;
          short sem_op;
          short sem_flg;
      }
      • sem_num : semaphore index
      • sem_op : ์ˆ˜ํ–‰ํ•  ์—ฐ์‚ฐ(์–‘์˜ ์ •์ˆ˜ ๋˜๋Š” ์Œ์˜ ์ •์ˆ˜ ๋˜๋Š” 0). sem_op๊ฐ€ -1์ด๋ฉด wait / +1์ด๋ฉด signal. -2, -3, -5๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋Š”๋ฐ ์ด ์ˆซ์ž๋“ค์„ ์ž˜ ์กฐํ•ฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ์˜ sem ๊ฐ€๋Šฅ.
      • sem_flg : IPC_NOWAIT or SEM_UNDO
        • ์ด๊ฑด ์ฃผ์˜ : ์‚ฌ์šฉํ•˜์ง€ ๋ง ๊ฒƒ. ํ•ญ์ƒ 0์œผ๋กœ ์„ค์ •ํ•  ๊ฒƒ
        • IPC_NOWAIT : sem ๊ธฐ๋ณธ์ ์œผ๋กœ blocking์„ ํ•ด์•ผํ•จ. block ํ•˜๊ธฐ ์‹ซ์–ด์„œ ์˜ต์…˜ ์‚ฌ์šฉํ•˜๋ฉด 0์ธ์ง€ ์•„๋‹Œ์ง€ ๊ฒ€์‚ฌ๋งŒ ํ•˜๊ณ  ๊ทธ๋ƒฅ ์ง€๋‚˜๊ฐ
        • SEM_UNDO : ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ํ›„ ์ข…๋ฃŒ๊นŒ์ง€ ์ง€๊ธˆ๊นŒ์ง€ ๋บ€ ๊ฐ’๋“ค์„ undoํ•จ. -10ํ–ˆ์œผ๋ฉด ๋งˆ์ง€๋ง‰์„ +10์„ ํ•ด์ฃผ๊ณ  ๋๋‚จ. ์ œ์ผ ๋งˆ์ง€๋ง‰์— ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ๋Œ์•„๊ฐ€๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•จ. ๊ทธ๋ž˜์„œ ๋‚˜์ค‘์— ์›์น˜์•Š๊ฒŒ ๊ผฌ์ผ ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ ๊ต์ˆ˜๋‹˜์ด ํ•˜์ง€๋ง๋ผ๊ณ  ํ•˜์‹ฌ
    • sem_op : ์ˆ˜ํ–‰ํ•  ์—ฐ์‚ฐ

      • ์Œ์ˆ˜ p() or wait() ์—ฐ์‚ฐ

        if(semval >= |sem_op|){
            set semval to semval - |sem_op|;
        }
        else{
            wait until semval reaches or exceeds |sem_op|;
            then set semval to semval - |sem_op|;
        }
      • ์–‘์ˆ˜ v() or signal() ์—ฐ์‚ฐ

        set semval to semval + |sem_op|;
        
      • 0

        semval ๊ฐ’์˜ ๋ณ€ํ™”๋Š” ์—†์Œ
        sem_op๋Š” semval์ด 0์ด ๋  ๋•Œ๊นŒ์ง€ waiting(blocking)
        //(์• ๋งคํ•จ)ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€, ํ•œ๊บผ๋ฒˆ์— ๋‹ค ํ’€์–ด์ค˜์„œ ํ•œ ๋ฒˆ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ•ด์ฃผ๊ธฐ
        
    • ์˜ˆ์ œ. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ทธ๋ƒฅ ๋ฉˆ์ถฐ๋ฒ„๋ฆผ. ์„ธ๋งˆํฌ waitํ–ˆ๋‹ค๊ฐ€ ์•ˆ ํ’€์–ด์ฃผ๋‹ˆ๊นŒ

      union semun{
              int val;
              struct semid_ds *buf;
              ushort *array;
      };
      
      int main(int argc, char **argv){
              int i, id, pid, semid;
              key_t key;
              union semun arg;
              ushort buf[3] = {0};
              struct sembuf p_buf;
      
              key = ftok("key", 1);
              semid = semget(key, 1, 0600|IPC_CREAT|IPC_EXCL);
      
              p_buf.sem_num = 0;	//0๋ฒˆ ์„ธ๋งˆํฌ
              p_buf.sem_op = -1;	//wait ๋ช…๋ น
              p_buf.sem_flg = 0;	//๊ทธ๋ƒฅ 0์œผ๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๊ทผ๋ฐ ๊ผญ 0์œผ๋กœ ์„ค์ •ํ•œ๊ฑฐ ๋ช…์‹œํ•˜๊ธฐ
              semop(semid, &p_buf, 1);
      
              printf("process %d in critical section\n", getpid());
              sleep(2);
              printf("process %d leaving critical section\n", getpid());
      
              p_buf.sem_num = 0;	//0๋ฒˆ ์„ธ๋งˆํฌ
              p_buf.sem_op = 1;	//signal ๋ช…๋ น
              p_buf.sem_flg = 0;	//๊ทธ๋ƒฅ 0์œผ๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๊ทผ๋ฐ ๊ผญ 0์œผ๋กœ ์„ค์ •ํ•œ๊ฑฐ ๋ช…์‹œํ•˜๊ธฐ
              semop(semid, &p_buf, 1);
      
              exit(0);
      }
    • ์ฑ…์—์„œ ์ฐพ์€ ์˜ˆ์ œ

      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <sys/wait.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <dirent.h>
      #include <string.h>
      #include <time.h>
      #include <ftw.h>
      #include <stdlib.h>
      #include <sys/mman.h>
      #include <sys/ipc.h>
      #include <sys/msg.h>
      #include <sys/sem.h>
      #include <sys/shm.h>
      
      #define BUFSIZE 512
      
      int initsem(key_t semkey){
          union semun arg;
          int status = 0, semid;
      
          semid = semget(semkey, 1, IPC_CREAT|IPC_EXCL|0600);
          if(semid == -1){
              semid = semget(semkey, 1, 0);
          }
          else{
              arg.val = 1;
              status = semctl(semid, 0, SETVAL, arg);
          }
      
          if(semid == -1 || status == -1){
              perror("initsem");
              return -1;
          }
      
          return semid;
      }
      
      int semlock(int semid){
          struct sembuf buf;
      
          buf.sem_num = 0;
          buf.sem_op = -1;
          buf.sem_flg = 0;
      
          if(semop(semid, &buf, 1) == -1){
              perror("semlock failed");
              exit(1);
          }
          return 0;
      }
      
      int semunlock(int semid){
          struct sembuf buf;
      
          buf.sem_num = 0;
          buf.sem_op = 1;
          buf.sem_flg = 0;
      
          if(semop(semid, &buf, 1) == -1){
              perror("semunlock failed");
              exit(1);
          }
          return 0;
      }
      
      void semhandle(){
          int semid;
          pid_t pid = getpid();
          key_t key;
      
          key = ftok("key", 1);
      
          if((semid = initsem(key)) < 0)
              exit(1);
      
          semlock(semid);
          printf("LOCK : Process %d\n", (int)pid);
          printf("***LOCK MODE : Critical Section\n");
          sleep(1);
          printf("UNLOCK : Process %d\n", (int)pid);
          semunlock(semid);
      
          exit(0);
      }
      
      int main(int argc, char **argv){
          int i;
          for(i=0;i<3;i++){
              if(fork()==0)
                  semhandle();
          }
      
          for(i=0;i<3;i++)
              wait(0);
      
          exit(0);
      }

Shared Memory

  • ๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฌผ๋ฆฌ์  ๋ฉ”๋ชจ๋ฆฌ์˜ ์ผ๋ถ€๋ฅผ ๊ณต์œ 

    • MemoryMapping์˜ ๊ฒฝ์šฐ, ์ˆ˜์ • ๋‚ด์šฉ์ด ๋ฐ”๋กœ ์ ์šฉ๋˜์ง€ ์•Š๊ณ  OS๊ฐ€ ๊ฐ€๋Šฅํ•œ ํƒ€์ด๋ฐ์— ์ˆ˜์ •์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ฐจ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๋™๊ธฐํ™”๊ฐ€ ์•ˆ ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋Š”๋ฐ
    • shared memory๋Š” ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ณต๊ฐ„์ด๋ผ ์ „ํ˜€ delay์—†์ด ์ƒ๋Œ€ํŽธ์ด ์ˆ˜์ •๋‚ด์šฉ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
  • OS์˜ ๊ฐ„์„ญ์—†์ด ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ€์žฅ ํšจ์œจ์ ์ธ IPC ๊ธฐ๋ฒ•์ด๋‹ค

  • shmget ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/types.h>
      #include <sys/ipc.h>
      #include <sys/shm.h>
      
      int shmget(key_t key, size_t size, int permflag);
    • key : ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์˜ identifier

    • size : ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์˜ ์ตœ์†Œ ํฌ๊ธฐ

    • permflag : access permission|IPC_CREAT|IPC_EXCL

      • ๋”ฑ ํ•œ์‚ฌ๋žŒ๋งŒ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ IPC_EXCL ์˜ต์…˜์„ ๋ถ™์—ฌ์คŒ. ์ดˆ๊ธฐํ™”ํ•  ๋•Œ, ํ•˜๋‚˜์˜ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑํ•˜์—ฌ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์–ฝํžˆ์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด์„œ ์‚ฌ์šฉ
    • return ๊ฐ’ : ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์˜ identifier

    • ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ ์˜ˆ์ œ

    //512byte์˜ ๋ฌธ์ž๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ
    shmid1 = shmget(key, 512, 0600|IPC_CREAT);
    
    //10๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ
    shmid2 = shmget(key, 10*sizeof(int), 0600|IPC_CREAT);
    
    //struct databuf์˜ ๋ฐ์ดํ„ฐ 5๊ฐœ๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ
    shmid3 = shmget(key, 5*sizeof(struct databuf), 0600|IPC_CREAT);
  • shmat ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • shmget ํ˜ธ์ถœ์— ์˜ํ•ด ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์ž์‹ ์˜ ๋…ผ๋ฆฌ์  ์ž๋ฃŒ ๊ณต๊ฐ„์— ๋ถ€์ฐฉ

    • ๋งŒ๋“  shared memory๋ฅผ ๋‚ด ์ฃผ์†Œ๊ณต๊ฐ„์— ์ €์žฅํ•ด์„œ, ๋‚˜์—๊ฒŒ ์ฃผ์†Œ๋ฅผ returnํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/shm.h>
      
      int *shmat(int shmid, const void *daddr, int shmflag);
    • shmid : ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ identifier

    • daddr : process address space ๋‚ด์˜ ๋ถ€์ฐฉ ์œ„์น˜, NULL์ธ ๊ฒฝ์šฐ ์‹œ์Šคํ…œ์ด ์œ„์น˜ ๊ฒฐ์ •. ๊ทธ๋ž˜์„œ ๊ทธ๋ƒฅ NULL์ด๋‚˜ 0์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค

    • shmflag : SHM_RDONLY(๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅ). ๊ทผ๋ฐ ๋ณดํ†ต ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋‹ค ํ• ๊ฑฐ๋ผ 0 ์ ์œผ๋ฉด ๋‘˜ ๋‹ค ํ•˜๋Š”๊ฑฐ๋ผ NULL์ด๋‚˜ 0์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค

    • return ๊ฐ’ : process๋‚ด์˜ ์œ ํšจ์ฃผ์†Œ, ์‹คํŒจ์‹œ (void*) -1

  • shmdt ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ํ”„๋กœ์„ธ์Šค์˜ ๋…ผ๋ฆฌ์  ์ฃผ์†Œ ๊ณต๊ฐ„์œผ๋กœ๋ถ€ํ„ฐ ๋–ผ์–ด๋‚ธ๋‹ค

    • ์‚ฌ์šฉ๋ฒ•

      int shmdt(memptr);
    • memptr : ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ๋Œ€ํ•œ ์œ ํšจ์ฃผ์†Œ. shmatํ•ด์„œ ๋ฐ›์€ ์ฃผ์†Œ๊ณต๊ฐ„์„ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

    • return ๊ฐ’ : 0 or -1

    • shmat์„ ์ด์šฉํ•œ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์ฐฉ ์˜ˆ์ œ

      //512byte์˜ ๋ฌธ์ž๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ ํ›„ ๋ถ€์ฐฉ
      buf1 = (char *)shmat(shmid1, 0, 0);
      
      //10๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ ํ›„ ๋ถ€์ฐฉ
      buf2 = (int *)shmat(shmid2, 0, 0);
      
      //struct databuf์˜ ๋ฐ์ดํ„ฐ 5๊ฐœ๋ฅผ ์ €์žฅํ•  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์ƒ์„ฑ ํ›„ ๋ถ€์ฐฉ
      buf3 = (struct databuf*)shmat(shmid3, 0, 0);
      • ์›๋ž˜ ๊ธฐ๋ณธ์œผ๋กœ ์ •์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ returnํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜• ๋ณ€ํ™˜์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.
    • ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ

      //ํ‘œ์ค€ ์ž…๋ ฅ์œผ๋กœ ์ฝ์€ ๋ฌธ์ž์—ด์„ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅ ํ›„ ์ถœ๋ ฅ
      n = read(0, buf1, 512);
      write(1, buf1, n);
      
      //ํ‘œ์ค€ ์ž…๋ ฅ์œผ๋กœ ์ฝ์€ 10๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅ ํ›„ ์ถœ๋ ฅ
      for(i=0;i<10;i++)
          scanf("%d", buf2+i);
      for(i=0;i<10;i++)
          printf("%d\n", *(buf2+i));
      
      //struct databuf์˜ ๋ฐ์ดํ„ฐ ์ค‘ d_nread์— 10์”ฉ ๋”ํ•˜๊ธฐ
      for(i=0;i<5;i++)
          (buf3+i)->d_nread += 10;
      
      //struct databuf์˜ ๋ฐ์ดํ„ฐ ์ค‘ d_nread์™€ d_buf ์ถœ๋ ฅํ•˜๊ธฐ
      for(i=0;i<5;i++)
          printf("%d ... %s\n", (buf3+i)->d_nread, (buf3+i)->d_buf);
  • shmctl ์‹œ์Šคํ…œ ํ˜ธ์ถœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <sys/shm.h>
      
      int shmctl(int shmid, int command, struct shmid_ds *shm_stat);
    • command

      • IPC_STAT : ์ •๋ณด ํ™•์ธ ๊ธฐ๋Šฅ. 3๋ฒˆ์งธ ์ธ์ž์— ์ €์žฅ
      • IPC_RMID : ์‚ญ์ œ ๊ธฐ๋Šฅ. 3๋ฒˆ์งธ ์ธ์ž๋Š” 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์‚ฌ์šฉ.

LOCK / UNLOCK

  • record locking

    • ํ•„์š”์„ฑ

      • 10๊ฐœ์˜ ์ˆซ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„์„œ ๊ฐ ์ž๋ฆฌ ์ˆซ์ž์— +10์„ ํ•ด์„œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ. 2๊ฐœ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•จ.

      • ๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•ด์„œ ๋งจ ์•ž์— ๊ฐ’์ด 80์œผ๋กœ ๋ผ์žˆ์œผ๋ฉด ํ•œ ๋ฒˆ +10ํ•˜๊ณ  ๋‚˜์ค‘์— ํ•œ ๋ฒˆ +10ํ•ด์„œ 100์œผ๋กœ ๊ฐ’์ด ๋ณ€๊ฒฝ๋ผ์žˆ์–ด์•ผํ•˜๋Š”๋ฐ, ๋จผ์ € ๋”ํ•œ ํ”„๋กœ์„ธ์Šค ์ž‘์—…์ด ๋А๋ ค์„œ 90์œผ๋กœ ๋ณ€๊ฒฝํ•œ ํ›„์— ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ’์„ ๊ฐ€์ ธ๊ฐ„๊ฒŒ ์•„๋‹ˆ๋ผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์ธ 80์ผ๋•Œ ๊ฐ’์„ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ€์ ธ๊ฐ€๋ฒ„๋ฆฌ๊ฒŒ ๋˜๋ฉด 2๋ฒˆ ์ž‘์—…์„ ํ–ˆ๋Š”๋ฐ ์ตœ์ข… ๊ฒฐ๊ณผ๊ฐ€ 90์œผ๋กœ ์„ค์ •๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Œ.

      • ๊ทธ๋ž˜์„œ lock์„ ํ•ด์ค˜์„œ ํ•œ ์‚ฌ๋žŒ์ด ์ฝ์–ด๊ฐ„ ๋™์•ˆ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์€ blocking์ด ๋˜๊ณ , ์ž‘์—… ๋๋‚œ ํ›„ lock์ด ํ’€๋ฆฌ๋ฉด ๊ฐ’์„ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ์Œ.

      • ๊ณ„์ขŒ ๊ด€๋ฆฌํ•˜๋Š” ์‹œ์Šคํ…œ ๊ฐ™์€ ๊ฒฝ์šฐ ์ค‘์š”ํ•œ ๋ฌธ์ œ

      • ์ž˜๋ชป๋œ ์ฝ”๋“œ. Lock/unlock ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ

        fd = open("data1", O_RDWR|O_CREAT, 0600);
        
        for(i=0;i<10;i++){
            read(fd, &num, sizeof(int));
            num = num + 10;
            sleep(1);
            lseek(fd, -sizeof(int), SEEK_CUR);
            write(fd, &num, sizeof(int));
            printf("%d\n", num);
        }
      • Locking / Unlocking ์‚ฌ์šฉ ์˜ˆ์ œ

        int main(void){
            int fd, i, num;
            struct flock lock;
            
            fd=open("data1", O_RDWR|O_CREAT, 0600);
            lock.l_whence=SEEK_CUR;
            lock.l_len=sizeof(int);
            
            for (i=0; i<10; i++){
                lock.l_type = F_WRLCK;
                lock.l_start = 0;
                fcntl(fd, F_SETLKW, &lock);
                read(fd, &num, sizeof(int));
                num=num + 10;
                sleep(1);
            }
            
            lseek(fd, -sizeof(int), SEEK_CUR);
            write(fd, &num, sizeof(int));
            lock.l_type = F_UNLCK;
            lock.l_start = -sizeof(int);
            fcntl(fd, F_SETLK, &lock);
            lseek(fd, 0, SEEK_SET);
            
            for (i=0; i<10; i++){
                read(fd, &num, sizeof(int));
                printf("%d\n", num);
            }
            return 0;
        }
      • ํ˜„์žฌ x = 100;

        P1 P2
        read x read x
        x = x + 100; x = x + 200;
        write x write x
        • p1, p2 ์‹คํ–‰ ํ›„ x์˜ ๊ฐ’์€ ์ œ๊ฐ๊ฐ์ด๋‹ค.
    • Locking

      • ํŠน์ • record์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ์ฝ๊ธฐ/์“ฐ๊ธฐ ์ œํ•œ
      • read lock : ์ฝ๊ธฐ๋Š” ํ—ˆ์šฉ, ์“ฐ๊ธฐ๋Š” ์ œํ•œ. ์ฝ๋Š”๊ฑด ๊ดœ์ฐฎ๊ณ  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ๋งŒ ์•ˆ ๋œ๋‹ค. ์ฝ๊ธฐ ์ž‘์—… ํ›„ ๋
      • wirte lock : ์ฝ๊ธฐ, ์“ฐ๊ธฐ ๋ชจ๋‘ ์ œํ•œ. ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ๊นŒ์ง€ํ•˜๋ฉด ์ด๊ฑฐ๋กœ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค.
    • Unlocking : ์ œํ•œ ํ•ด์ œ

    • ์‚ฌ์šฉ๋ฒ•

      #include <fcntl.h>
      
      int fcntl(int filedes, int cmd, struct flock *ldata);
    • filedes : lock์„ ์„ค์ •ํ•˜๋ ค๋Š” file์˜ descriptor

      • read-lock : O_RDONLY / O_RDWR๋กœ open๋œ ํŒŒ์ผ์— ํ•œํ•ด์„œ ์ ์šฉ ๊ฐ€๋Šฅ
      • write-lock : O_WRONLY / O_RDWR๋กœ open๋œ ํŒŒ์ผ์— ํ•œํ•ด์„œ ์ ์šฉ ๊ฐ€๋Šฅ
    • cmd

      • F_GETLK : lock ์ •๋ณด ์–ป๊ธฐ. ํ•ด๋‹น ์ •๋ณด๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜์— ์ €์žฅ. ๋ˆ„๊ฐ€ lock๊ฑธ์—ˆ๋Š”์ง€ ์ •๋ณด ์–ป๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ
      • F_SETLK : non-blocking locking or unlocking. Lock ์„ค์ •์— ๊ด€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜์— ์ง€์ •
      • F_SETLKW : blocking locking. Lock ์„ค์ •์— ๊ด€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜์— ์ง€์ •
    • Struct flock *ldata ๊ตฌ์กฐ

      • short l_type : lock์˜ type. F_RDLCK, F_WRLCK, F_UNLCK
      • short l_whence : SEEK_SET, SEEK_CUR, SEEK_END
      • off_t l_start : l_whence๋กœ๋ถ€ํ„ฐ์˜ ๋ณ€์œ„๋กœ ํ‘œํ˜„๋œ locked record์˜ ์‹œ์ž‘ ์œ„์น˜
      • off_t l_len : locked record์˜ ๊ธธ์ด. ์ •์ˆ˜๋Š” 4๋ฐ”์ดํŠธ, ๋ฌธ์ž๋Š” ์ž„์˜์˜ ๊ธธ์ด๋ฐ”์ดํŠธ, ๊ตฌ์กฐ์ฒด๋Š” ์›์†Œ ํ•˜๋‚˜์”ฉ ์ง€์ •
      • pid_t l_pid : F_GETLK์˜ ๊ฒฝ์šฐ๋งŒ ์œ ํšจ. ์ด ์˜ต์…˜ ์‚ฌ์šฉํ•˜๋ฉด pid ๋ˆ„๊ฐ€ ํŒŒ์ผ์— lock์„ ๊ฑธ์—ˆ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ.
  • lock์€ ํ•œ ํ”„๋กœ์„ธ์Šค๋งŒ ๊ฑธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— lock์ •๋ณด๋Š” fork()์— ์˜ํ•ด ๊ณ„์Šน๋˜์ง€ ์•Š๋Š”๋‹ค. child์™€ parent๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์ด๊ธฐ ๋•Œ๋ฌธ์ž„

  • ๋ชจ๋“  lock์€ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ์‹œ ์ž๋™์œผ๋กœ unlock ๋œ๋‹ค

  • 2๊ฐœ ์ด์ƒ์˜ lock์„ ๊ฑธ๋ ค๊ณ  ํ•˜๋ฉด ๊ต์ฐฉ ์ƒํƒœ(deadlock)์ด ๋ฐœ์ƒ ๊ฐ€๋Šฅํ•˜๋‹ค

    • ๊ต์ฐฉ์ƒํƒœ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ fcntl ์‚ฌ์šฉํ•˜๋ฉด F_SETLKW ๋ช…๋ น์— ๋Œ€ํ•ด -1 return์„ ํ•œ๋‹ค. ์›ฌ๋งŒํ•˜๋ฉด deadlock์„ ๊ฒ€์ƒ‰๊ฐ€๋Šฅํ•œ๊ฑฐ์ง€, ๋ชจ๋“  deadlock์„ ๋‹ค ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
    • errno๋Š” EDEADLK
P1 P2
1. A์— lock 2. B์— lock
3. B์— lock 4. A์— lock
p2๋๋‚ ๋•Œ๊นŒ์ง€ block ์ด๋•Œ fcntl ์‚ฌ์šฉํ•˜๋ฉด -1 returnํ•จ