-
์์ ์ฌ์ฉํ 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
- ์ฝ๊ธฐ ๊ฐ๋ฅ : ํ ํตํด์ ๋ฉ์ธ์ง ๋ฐ์ ์ ์์
- ์ฐ๊ธฐ ๊ฐ๋ฅ : ํ ์ด์ฉํด์ ๋ฉ์ธ์ง ๋ณด๋ผ ์ ์์
- ์คํ ๊ฐ๋ฅ : (์ฝ๊ธฐ/์ฐ๊ธฐ๋ง ํ ๊ฑฐ๋ผ ์คํ์ ์ ์. ์๋ฏธ ์์)
- 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 passing
- message queue๋ฅผ ํตํ message ์ ๋ฌ
- msgget : queue ์์ฑ
- msgsnd : message ๋ณด๋ด๊ธฐ
- msgrcv : message ๋ฐ๊ธฐ
- message queue๋ฅผ ํตํ 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์ ๊ฐ์ด ์ฌ์ฉํด์ผํจ
- 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
- IPC_NOWAIT
-
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
-
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); }
-
-
๋ ์ด์์ ํ๋ก์ธ์ค๊ฐ ๋ฌผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ์ ์ผ๋ถ๋ฅผ ๊ณต์
- 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์ผ๋ก ์ค์ ํ๊ณ ์ฌ์ฉ.
-
-
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ํจ |