메시지큐

입출력 데이터를 커널 내부에 메시지 리스트 형태로 보관

메시지 타입으로 선택적으로 메시지 검색 가능

메일 시스템과 유사, 서버, 클라이언트 두 프로세스는 동일한  시점에서 존재할 필요가 없음

 

메시지큐 함수

struct msgbuf{

  long mtype; // msg type

  char mtext[SOMEVALUE]; //msg text (data)

};

msgsnd 함수의 flag 인자, IPC_NOWAIT: 메시지큐가 다 찼으면 errno=EAGAIN

msgrcv 함수의 flag 인자, MSG_NOERROR: 해당 메시지가 주어진 length보다 클 때 truncate해서 리턴

msgrcv 함수의 msgtype 인자

-msgtype=0 첫 번째 미시지를 리턴

-msgtype>0 type이 같은 첫 번째 메시지를 리턴

-msgtype<0 msgtype 절대값보다 작거나 같은 type의 첫 번째 메시지를 리턴

 

서버

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
#define MSQKEY 34856
#define MSQSIZE 32
 
struct mymsgbuf{
    long mtype;
    char mtext[MSQSIZE];
};
 
int main()
{
    key_t key;
    int n, msqid;
    struct mymsgbuf mb;
 
    key = MSQKEY;
 
    if((msqid=msgget(key,IPC_CREAT |IPC_EXCL|0666))<0){
        perror("msgget");
        return -1;
    }
 
    while((n=msgrcv(msqid, &mb, MSQSIZE,0,0))>0){
        switch (mb.mtype){
            case 1:
                write(1,mb.mtext,n); break;
            case 2:
                goto out;
        }
    }
    out:
    if(msgctl(msqid,IPC_RMID,(struct msqid_ds *)0)<0){
        perror("msgctl");
        return -1;
    }
    return 0;
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

클라이언트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
 
 
#define MSQKEY 34856
#define MSQSIZE 32
 
struct mymsgbuf{
    long mtype;
    char mtext[MSQSIZE];
};
 
int main()
{
    key_t key;
    int n,msqid;
    struct mymsgbuf mb;
 
    key=MSQKEY;
 
    if((msqid=msgget(key,0666))<0){
        perror("msgget");
        return -1;
    }
    mb.mtype=1;
    while((n=read(0,mb.mtext,MSQSIZE))>0){
        if(msgsnd(msqid,&mb,n,0)<0){
            perror("msgsnd");
            return -1;
        }
    }
    mb.mtype=2;
    memset(mb.mtext,0,MSQSIZE);
    if(msgsnd(msqid,&mb,MSQSIZE,0)<0){
        perror("msgsnd");
        return -1;
    }
    return 0;
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

 

세마포어

다수의 자원을 놓고 경쟁하는 프로세스들 사이에서 필요한 동기화 기법

자원의 수를 기록하는 세마포어 변수와 P,V 연산으로 동기화

 

 

key12345 를 이용해서 세마포어를 생상하며 퍼미션은 0666으로 설정, 세마포어의 크기는 1로 잡혀 있다( 대부분1).

만약 기존에 key 12345 로 이미 만들어진 세마포어가 있따면 새로 생성하지 않고 기존의 세마포어에 접근

1
2
3
4
5
6
7
8
9
10
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
 
int main()
{
    int semid;
    semid = semget((key_t)1234510666 | IPC_CREAT);
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

 

공유메모리

프로세스 간에 공유 메모리를 설정하여 커널 버퍼 경유를 없앰

메모리 복사 횟수를 줄여 성능 향상

세마포어와 같은 동기화 기법 필요

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdio.h>
 
int main()
{
    int shmid;
    int pid;
    int *cal_num;
    void *shared_memory=(void *)0;
 
    //공유메모리 공간을 만든다..
    shmid=shmget((key_t)1234,sizeof(int),0666|IPC_CREAT);
 
    if(shmid==-1){
        perror("shmget failed :");
        return -1;
    }
 
    //공유메모리를 사용하기 위해 프로세스 메모리에 붙인다.
    shared_memory = shmat(shmid, (void *)0,0);
    if(shared_memory==(void*)-1){
        perror("shmat failed : ");
        return -1;
    }
 
    cal_num = (int *)shared_memory;
    pid=fork();
    if(pid==0){
        shmid=shmget((key_t)1234,sizeof(int),0);
        if(shmid==-1){
            perror("shmget failed :");
            return -1;
        }
 
        
        shared_memory=shmat(shmid, (void *)0,0666|IPC_CREAT);
        if(shared_memory == (void *)-1){
            perror("shmat failed :");
            return -1;
        }
        cal_num=(int *)shared_memory;
        *cal_num=1;
 
        while(1){
            *cal_num=*cal_num+1;
            printf("child %d\n",*cal_num);
            sleep(1);
        }
    } else if(pid>0){ //부모 프로세스로 공유메모리의 내용을 표시
        while(1){
            sleep(1);
            printf("%d\n",*cal_num);
        }
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

+ Recent posts