Louie NRT Story

[RasbperryPi] Shared Memory Queue 본문

에너지

[RasbperryPi] Shared Memory Queue

hyeok0724.kim@gmail.com 2019. 5. 6. 21:33
반응형

[First Process]

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
 
#include <string.h> 
#include <unistd.h> 
 
#define QUEUE_SIZE 10
 
// 생산자와 소비자간 공유할 데이터
struct data
{
    char name[80]; 
};
 
struct flock lock, unlock;
 
int lock_open(int fd, int index)
{
  lock.l_start  = index;
  lock.l_type = F_WRLCK;
  lock.l_len = 1;
  lock.l_whence = SEEK_SET;
  return fcntl(fd, F_SETLKW, &lock);
}
 
int lock_close(int fd, int index)
{
  unlock.l_start  = index;
  unlock.l_type = F_UNLCK;
  unlock.l_len = 1;
  unlock.l_whence = SEEK_SET;
  return fcntl(fd, F_SETLK, &unlock);
}
 
void lock_init()
{
  lock.l_start  = 0;
  lock.l_type = F_WRLCK;
  lock.l_len = 1;
  lock.l_whence = SEEK_SET;
}
void unlock_init()
{
  unlock.l_start  = 0;
  unlock.l_type = F_UNLCK;
  unlock.l_len = 1;
  unlock.l_whence = SEEK_SET;
}
 
int main()
{
    int shmid;
    int i = 0;
    int offset = 0;
 
    struct data *cal_num;
    void *shared_memory;
    struct data ldata;    
    int fd;
 
    lock_init();
    unlock_init();
 
    // 잠금 파일을 생성한다.
    if ((fd = open("shm_lock", O_CREAT|O_RDWR)) < 0)
    {
        perror("file open error ");
        exit(0);
    }
    // 파일을 공유메모리 큐의 크기만큼 만든다.
    write(fd, (void *)'\0'sizeof(char)*QUEUE_SIZE);
 
    // 공유메모리를 생성한다.
    // 공유메모리의 크기는 QUEUE_SIZE * 원소의 크기가 된다.  
    shmid = shmget((key_t)1234sizeof(ldata)*QUEUE_SIZE, 0666|IPC_CREAT);
    if (shmid == -1)
    {
        perror("shmget failed : ");
        exit(0);
    }
 
    // 공유할 메모리의 크기를 할당하고 이를 공유 메모리영역에 붙인다.  
    shared_memory = (void *)malloc(sizeof(ldata)*QUEUE_SIZE);
    shared_memory = shmat(shmid, (void *)00);
    if (shared_memory == (void *)-1)
    {
        perror("shmat failed : ");
        exit(0);
    }
 
    while(1)
    {
        // 공유할 데이터 
        sprintf(ldata.name, "write Data : %d\n",i);
        // 이건 디버깅용 출력물
        printf("%d %s",(i==0)? QUEUE_SIZE - 1:i-1ldata.name);
 
        // 레코드를 잠근다.
        if(lock_open(fd, i)< 0)
        {
            perror("lock error");
        }
        // 레코드 잠금을 얻었다면
        // 이전 레코드의 잠금을 푼다.
        if(lock_close(fd, (i==0)? QUEUE_SIZE - 1: i-1< 0)
        {
            perror("flock error");
        }
        // 공유메모리에 데이터를 쓴다.
        memcpy((void *)shared_memory+offset, (void *)&ldata, sizeof(ldata));
        sleep(1);
        offset += sizeof(ldata);
        i++;
 
        // 이건 순환 큐이다. 만약 큐의 크기를 모두 채웠다면 
        // offset과 인덱스 번호 i를 초기화 한다.
        if (i == QUEUE_SIZE) {i = 0; offset = 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

 

[Second Process]

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
 
#include <string.h> 
#include <unistd.h> 
 
#define QUEUE_SIZE 10
 
struct data
{
    char name[80]; 
};
 
struct flock lock, unlock;
 
int lock_open(int fd, int index)
{
    lock.l_start    = index; 
    lock.l_type = F_WRLCK;
    lock.l_len = 1;
    lock.l_whence = SEEK_SET;
    return fcntl(fd, F_SETLKW, &lock);
}
 
int lock_isopen(int fd, int index)
{
    lock.l_start    = index; 
    lock.l_type = F_WRLCK;
    lock.l_len = 1;
    lock.l_whence = SEEK_SET;
    return fcntl(fd, F_SETLK, &lock);
}
 
int lock_close(int fd, int index)
{
    unlock.l_start    = index; 
    unlock.l_type = F_UNLCK;
    unlock.l_len = 1;
    unlock.l_whence = SEEK_SET;
    return fcntl(fd, F_SETLK, &unlock);
}
 
void lock_init()
{
  lock.l_start  = 0;
  lock.l_type = F_WRLCK;
  lock.l_len = 1;
  lock.l_whence = SEEK_SET;
}
void unlock_init()
{
  unlock.l_start  = 0;
  unlock.l_type = F_UNLCK;
  unlock.l_len = 1;
  unlock.l_whence = SEEK_SET;
}
 
int main()
{
    int shmid;
    int i = 0;
    int offset = 0;
  int fd;
 
    void *shared_memory;
    struct data *ldata;    
    lock_init();
    unlock_init();
 
  if ((fd = open("shm_lock", O_RDWR)) < 0)
  {
      perror("file open error ");
       exit(0);
  }
 
    shmid = shmget((key_t)1234sizeof(struct data)*QUEUE_SIZE, 0666);
    if (shmid == -1)
    {
        perror("shmget failed : ");
        exit(0);
    }
 
    shared_memory = (void *)malloc(sizeof(ldata)*QUEUE_SIZE);
    shared_memory = shmat(shmid, (void *)00);
    if (shared_memory == (void *)-1)
    {
        perror("shmat failed : ");
        exit(0);
    }
 
    // 이 부분은 생산자가 가장 최근에 쓴 데이터의 인덱스를 
    // 찾아내기 위한 코드다.  
    // 잠금 파일의 레코드를 차례대로 검사하면서 잠금이 있는 부분을 검사한다. 
    // 잠금이 검사되면, 리턴한다.  
    while(1)
    {
        if(lock_isopen(fd, i)< 0)
        {
            if (errno == EAGAIN)
            {
                printf("Read index is %d %d %d\n", i, EAGAIN, errno);
                fcntl(fd, F_GETLK, &lock);  // 코드 1 
                offset = sizeof(struct data)*i; 
                break;
            }
            else
            {
                printf("Init Error\n");
                exit(0);
            }
        }
        lock_close(fd, i);
        i++;
        if (i == QUEUE_SIZE)
        {
            printf("Server Error\n");
        }
    }
 
    // 공유 메모리로 부터 데이터를 읽는다.
    while(1)
    {
        if (lock_open(fd, i) < 0)
        {
            perror("flock error");
        }
        ldata = (struct data *)(shared_memory+offset);
        printf("%s",ldata->name);    
        lock_close(fd, i);
 
        offset += sizeof(struct data);
        i++;
        if (i == QUEUE_SIZE) {i = 0;offset = 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
반응형
Comments