[Linux] IPC : Shared Memory 통신 Example Source [Client / Server]

Posted by [하늘이]
2016. 11. 29. 16:30 IT/Linux
반응형

Beginning Linux Programming 14장

IPC 통신 타입중 Shared Memory 방식에 대한 샘플 소스 입니다.

Test_IPC_SharedMemory.tar.gz


한쪽에서는 Keyboard 에서 입력된 데이터를 전송하고, 한쪽에서는 전송 받은 데이터를 화면에 찍는 샘플 소스 입니다.

실행 시 아래와 같은 결과가 나오게 되어 있습니다.

왼쪽이 서버, 오른쪽이 클라이언트라고 생각하시면 됩니다.


위 방식의 단점, Server 단에서 shared memory 가 변경된지 지속적으로 Polling 하고 있어 불필요한 리소스가 낭비되게 됩니다.

보완을 위하여는 다른 IPC : 메시지 대기열 등과 같은 통신을 추가하고 Signal wait...등을 사용하는 것이 좋아 보이네요.


첨부된 파일의 소스는 아래와 같습니다.


API 설명은 아래 링크를 참고하세요.

* shmget()

http://forum.falinux.com/zbxe/index.php?document_srl=423456&mid=C_LIB

* shmat()

http://forum.falinux.com/zbxe/index.php?document_srl=426100&mid=C_LIB

* shmdt()

http://forum.falinux.com/zbxe/index.php?document_srl=426102&mid=C_LIB


소스


Server

-----------------testIpcShardMemory.h----------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    
#ifndef TESTIPCSHARDMEMORY_H_
#define TESTIPCSHARDMEMORY_H_
 
 
 
#define TEXT_SIZE 2048
#define KEY_ID 2016
 
 
struct shared_use_st {
    int written_by_you;
    char data[TEXT_SIZE];
};
 
 
 
#endif /* TESTIPCSHARDMEMORY_H_ */
cs

-----------------------------Test_IPC_SharedMemory_Server.cpp-----------------------------

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
 
 
#include "testIpcShardMemory.h"
 
using namespace std;
 
int main() {
 
    int running = 1;
    void *pShardMemory = (void*)0;
    struct shared_use_st *pShardStuff;
    int shmId;
 
    srand((unsigned int)getpid());
 
    shmId = shmget((key_t)KEY_ID, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
 
    if(shmId == -1){
        cout << "[Servier][Error]shmget fail. id:" << shmId << endl;;
        exit(EXIT_FAILURE);
    }
 
    pShardMemory = shmat(shmId, (void*)00);
    if(pShardMemory == (void*)-1){
        cout << "[Servier][Error]shmat fail."<< endl;;
        exit(EXIT_FAILURE);
    }
    else{
        pShardStuff = (struct shared_use_st *) pShardMemory;
        pShardStuff->written_by_you = 0;
        cout << "[Servier]shmat success. flag:" << pShardStuff->written_by_you << endl;;
 
        while(running){
//            cout << "[Servier]while()"<< endl;
 
            if(pShardStuff->written_by_you == 1){
                cout << "[Servier]echo data:" << pShardStuff->data << endl;
 
                pShardStuff->written_by_you = 0;
 
 
                if(strncmp(pShardStuff->data, "end"3== 0){
                    running = 0;
                }
            }
        }
 
        if(shmdt(pShardMemory) == -1){
            cout << "[Servier][Error] shmdt fail."<< endl;;
            exit(EXIT_FAILURE);
        }
 
        if(shmctl(shmId, IPC_RMID, 0== -1){
            cout << "[Servier][Error] shmctl (IPC_RMID) failed."<< endl;;
            exit(EXIT_FAILURE);
        }
    }
 
    exit(EXIT_SUCCESS);
    //return 0;
}
 
cs





Client 

---------------------Test_IPC_SharedMemory_Client.cpp-----------------------------

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
 
 
#include "testIpcShardMemory.h"
 
using namespace std;
 
int main() {
 
    int running = 1;
    void *pShardMemory = (void*)0;
    struct shared_use_st *pShardStuff;
    int shmId;
    char buffer[TEXT_SIZE];
 
    srand((unsigned int)getpid());
 
    shmId = shmget((key_t)KEY_ID, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
 
    if(shmId == -1){
        cout << "[Client][Error]shmget fail. id:" << shmId << endl;;
        exit(EXIT_FAILURE);
    }
 
    pShardMemory = shmat(shmId, (void*)00);
    if(pShardMemory == (void*)-1){
        cout << "[Client][Error]shmat fail."<< endl;;
        exit(EXIT_FAILURE);
    }
    else{
        pShardStuff = (struct shared_use_st *) pShardMemory;
 
        cout << "[Client]shmat success. flag:" << pShardStuff->written_by_you << endl;;
 
        while(running){
 
            while(pShardStuff->written_by_you == 1){
                sleep(1);
            }
 
            cout << "[Client]Enter text :"<< endl;
            fgets(buffer, TEXT_SIZE, stdin);
 
            strncpy(pShardStuff->data, buffer, TEXT_SIZE);
            pShardStuff->written_by_you = 1;
            if(strncmp(pShardStuff->data, "end"3== 0){
                running = 0;
            }
        }
 
        if(shmdt(pShardMemory) == -1){
            cout << "[Client][Error] shmdt fail."<< endl;;
            exit(EXIT_FAILURE);
        }
    }
 
    exit(EXIT_SUCCESS);
    //return 0;
}
 
Colored by Color Scripter
cs
 
cs


반응형