memory & data management. linux system programming contents 동적 메모리 관리 memory...

25
Memory & Data Management

Upload: randall-mason

Post on 16-Dec-2015

233 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Memory & DataManagement

Page 2: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

Contents

동적 메모리 관리 Memory Allocation Memory De-allocation

파일 잠금 협조형 잠금 공유파일 구역 잠금 교착상태 (deadlock) 회피하기

Kongju national University

Page 3: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

1. Memory Management in C

C 언어 에서 main memory 할당하기 특정 물리적인 주기억 공간을 직접 할당하지

않음 각 프로세스는 할당된 data 영역의 기억공간을

사용 구조체 (struct) 로 선언된 데이터는 memory

할당을 한 뒤 사용해야 함 최대 할당 크기는 4GB, 32bit pointer 사용 Flat 32 bit memory Model

Kongju national University

Page 4: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

malloc()

#include <stdlib.h>

void *malloc(size_t size);

- size_t : unsigned int

- 결과는 pointer 로 반환 한다

- 메모리 할당은 커널 (kernel) 에서 담당

- 물리적 메모리 한계를 넘는 요구시 , swap 공간 (swap space) 를 사용

- Unix 에서 swapping 은 4096 bytes page 단위로 동작

- virtual memory management 의 Paging 기법

- 최대 할당할 수 있는 크기는 주기억공간 + swap 공간 보다 작다

- malloc() 의 size 를 넘어서는 메모리 사용시 error(segmentation fault !)

Kongju national University

Page 5: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

malloc() : 간단한 메모리 할당

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#define A_MEGABYTE (1024 * 1024)

main() {

char *some_memory;

int megabyte = A_MEGABYTE;

some_memory = (char *)malloc(megabyte);

if (some_memory != NULL) {

sprintf(some_memory, "Hello World\n");

printf("%s", some_memory);

}

}

Kongju national University

Page 6: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

malloc() 관련 reference codes

memory1.c : 간단한 memory allocation memory2.c : 모든 physical memory

allocation memory3.c : 최대 할당 가능한 memory

크기 시험 ( 동시에 여러 프로세스가 동작 때 이상 발생 )

memory4.c : memory 한번 남용해 보기

Kongju national University

Page 7: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

memory1.c 간단한 메모리 할당

#include <unistd.h>#include <stdlib.h>#include <stdio.h>

#define A_MEGABYTE (1024 * 1024)

main() { char *some_memory; int megabyte = A_MEGABYTE; some_memory = (char *)malloc(megabyte); if (some_memory != NULL) { sprintf(some_memory, "Hello World\n"); printf("%s", some_memory); } }

Kongju national University

Kongju national University

Page 8: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

memory2.c 모든 물리 메모리 할당

#include <unistd.h>#include <stdlib.h>#include <stdio.h>

#define A_MEGABYTE (1024 * 1024)

main() { char *some_memory; size_t size_to_allocate = A_MEGABYTE; int megs_obtained = 0;

while (megs_obtained < 2048) { some_memory = (char *)malloc(size_to_allocate); if (some_memory != NULL) { megs_obtained++; sprintf(some_memory, "Hello World"); printf("%s - now allocated %d Megabytes\n", some_memory, megs_obtained); } else { printf(“\n Memory allocation failure\n”); } }}

Kongju national University

Page 9: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

memory3.c 유효한 메모리 크기 측정

#include <unistd.h> #include <stdlib.h> #include <stdio.h>

#define ONE_K (1024)

main() { char *some_memory; int size_to_allocate = ONE_K; int megs_obtained = 0; int ks_obtained = 0;

while (1) { for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) { some_memory = (char *)malloc(size_to_allocate); if (some_memory == NULL) printf(“allocation failure\n”); sprintf(some_memory, "Hello World"); } megs_obtained++; printf("Now allocated %d Megabytes\n", megs_obtained); } printf(“allocation success\n”); }

Kongju national University

Page 10: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

memory4.c 메모리 남용해 보기

#include <unistd.h> #include <stdlib.h>

#define ONE_K (1024)

main() { char *some_memory; char *scan_ptr; some_memory = (char *)malloc(ONE_K); if (some_memory == NULL) printf(“allocation failure\n”);

scan_ptr = some_memory; while(1) { *scan_ptr = '\0'; scan_ptr++; } printf(“allocation success\n”); }

Kongju national University

Page 11: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

Null Pointer 접근

memory 공간에 자리 잡지 않은 ( 즉 할당이 안된 ) 데이터

Unix/Linux 에서는 허용하지 않음#include <unistd.h>#include <stdlib.h>#include <stdio.h>

main() { char *some_memory = (char *)0;

printf("A read from null %s\n", some_memory); sprintf(some_memory, "A write to null\n"); }

결과 :A read from null (null) : GNU C library 에서는 null 문자 제공segmentation fault(core dumped) : null string 에 쓰기는 error

Kongju national University

Page 12: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

또 다른 null pointer 접근 예#include <unistd.h>#include <stdlib.h>#include <stdio.h>

main() { char z = *(const char *)0; printf("I read from location zero\n");

}결과 :

segmentation fault(core dumped) : memory 위치 0 로 부터 직접 읽기 , 이는 허용되지 않음

Kongju national University

Page 13: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

free() : 할당된 메모리 해제

#include <stdlib.h>

void free(void *ptr_to memory);

- 이전에 할당된 메모리를 pointer 를 통하여 접근

- 접근 한 뒤 release

- 한번 해제 한 memory 공간은 그 프로세스에 다시 할당된다는 보장이 없음( 다른 프로세스에서 사용 가능성이 있음 )

- 따라서 free() 를 시행한 memory pointer 는 다시 접근 불가

Kongju national University

Page 14: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

free() 의 예

#include <stdlib.h>

#define ONE_K (1024)

main()

{

char *some_memory;

some_memory = (char *)malloc(ONE_K);

if (some_memory != NULL) {

free(some_memory);

}

}

Kongju national University

Page 15: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

그외 memory 관리 함수

#include <stdlib.h>

void *calloc(size_t no_of_element, size_t element_size);

void *realloc(void *existing_memory, size_t new_size);

- calloc() 은 malloc() 과 유사하나 동일 data 형식에 대하여 array 형태로 memory allocation 시행 (0 으로 채움 )

- 연속된 memory 를 할당한다는 보장이 없음 ( 주의 !!)

- realloc() 은 이미 할당된 메모리 블록의 크기를 확장

- 이미 할당된 영역에서 연장할 수 없다면 다른 빈 공간으로 이동

- 따라서 반드시 새로 return 되는 pointer 를 사용해야 함

Kongju national University

Page 16: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

2. File Locking

Linux 는 다중 사용자 / 다중 프로세스 환경 특정 파일이나 특정 device 를 일시 독점적

사용이 필요 예

lpr process 에 의한 특정 프린터 출력 시 충돌 방지 필요 /dev/modem 의 사용 시 특정 프로세스에서 독점 사용 필요

File locking 은 Linux 의 중요 기능 Locking method

파일 전체 잠금 : atomic way 파일 부분 잠금 : 파일 내용중 특정 부분만

Kongju national University

Page 17: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

잠금 표식 파일 생성

Printer daemon 에 의한 다수 출력물 충돌 방지 /usr/spool/lpr/lock file 을 일시 생성 , 프린트 완료 후 제거 위 파일을 잠금 표식 파일 (Locking Indicator file)

일종의 binary Semaphore 파일의 생성은 low level system call 사용

open(), read(), write(), close()

Kongju national University

Page 18: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

Locking file creation

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>

main(){ int file_desc; int save_errno;

file_desc = open("/tmp/LCK.test", O_RDWR | O_CREAT | O_EXCL, 0444);

if (file_desc == -1) { save_errno = errno; printf("Open failed with error %d\n",save_errno); } else { printf("Open succeeded\n"); } exit(EXIT_SUCCESS);}

동작 방법

% lock1

Open Succeeded

% lock1

Open failed with error 17

- errno : /usr/include/errno.h참조

- 이 프로그램은 종료 된 뒤에도 lock file은 계속 존재

- 따라서 실행 중에만 lock file을 사용하는 critical section을 사용하기 위해서는 다른 방법 필요

Kongju national University

Page 19: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

File locking: Critical section

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <fcntl.h>

#include <errno.h>

const char *lock_file = "/tmp/LCK.test2";

main() {

int file_desc;

int tries = 10;

while (tries--) {

file_desc = open(lock_file, O_RDWR | O_CREAT | O_EXCL, 0444);

if (file_desc == -1) {

printf("%d - Lock already present\n", getpid());

sleep(3);

}

- 따라서 실행 중에만 lock file을 사용하는 critical section을 사용하기 위해서는 다른 방법 필요

- 프로그램 수행 중 독점적인 기능을 사용할 때는 lock file을 생성한 뒤 locking을 하고

- 해제 (release)를 할 시점에는 close() -> unlink() 함수 사용

Kongju national University

Page 20: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

continue!

else { /* critical region */ printf("%d - I have exclusive access\n", getpid()); sleep(1); (void)close(file_desc); (void)unlink(lock_file); /* non-critical region */ sleep(2); } } /* while */ printf(“Done . . .\n”);}

실행 방법

% rm /tmp/LCK.test2

% lock2 & lock2

- 두 프로세스에서 동시에 locking을 시도하게 되고 먼저 시작된 프로세스에서 lock file을 생성하고 critical section에 들어 감

Kongju national University

Page 21: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

fcntl() : 파일 구역 잠그기

#include <fcntl.h>

int fcntl(int fildes, int command,

struct flock *flock_struct);

command: 잠금 명령 (F_GETLK, F_SETLK, F_SETLKW)

struct flock :

short l_type = F_RDLCK( 공유잠금 ),F_UNLCK( 해제 ),F_WRLCK(배타적잠금 )

short l_whence = SEEK_SET, SEEK_CUR, SEEK_END (unistd.h 에 정의 )

off_t l_start = 파일내 영역중 잠금의 시작 (bytes)

off_t l_len = l_start 부터의 잠금영역의 크기 (bytes)

pid_t l_pid = 잠금 프로세스의 pid

Kongju national University

Page 22: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

fcntl() continue !

command: 잠금 명령

F_GETLK : 잠금 정보 구하기 , 실제 lock 하지 않음 ,

다른 프로세스에 의한 locking 방지 , flock 구조체 전체 사용

* 이미 다른 프로세스에 의해 잠긴 경우 : flock 구조체에 정보 채워서 반환

* 잠겨 있지 않는 경우 : flock 구조체 변경 없이 반환

* file 의 locking 정보 구하기 실패하면 – 1 반환

F_SETLK : 실제 locking, l_type, l_pid 만 사용

F_SETLKW : F_GETLK 시행 후 다른 프로세스에 의해 잠긴 경우 waiting 명령

struct flock :

short l_type = F_RDLCK( 공유잠금 ),F_UNLCK( 해제 ),F_WRLCK( 배타적잠금 )

short l_whence = SEEK_SET, SEEK_CUR, SEEK_END (unistd.h 에 정의 )

off_t l_start = 파일내 영역중 잠금의 시작 (bytes)

off_t l_len = l_start 부터의 잠금영역의 크기 (bytes)

pid_t l_pid = 잠금 프로세스의 pidKongju national University

Page 23: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

fcntl() : example code - p1

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <fcntl.h>

const char *test_file = "/tmp/test_lock";

main() {

int file_desc;

int byte_count;

char *byte_to_write = "A";

struct flock region_1;

struct flock region_2;

int res;

/* open a file descriptor */

file_desc = open(test_file, O_RDWR | O_CREAT, 0666);

if (!file_desc) {

fprintf(stderr, "Unable to open %s for read/write\n",test_file);

exit(EXIT_FAILURE);

}/* if */

- lock대상 파일은 100bytes 크기

- 위치는 /tmp/test.lock

- 두개의 영역에 걸쳐 locking

Kongju national University

Page 24: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

fcntl() : example code – p2

/* put some data in the file */

for(byte_count = 0; byte_count < 100; byte_count++) {

(void)write(file_desc, byte_to_write, 1);

}/* for */

/* setup region 1, a shared lock, from bytes 10 -> 30 */

region_1.l_type = F_RDLCK;

region_1.l_whence = SEEK_SET;

region_1.l_start = 10;

region_1.l_len = 20;

/* setup region 2, an exclusive lock, from bytes 40 -> 50 */

region_2.l_type = F_WRLCK;

region_2.l_whence = SEEK_SET;

region_2.l_start = 40;

region_2.l_len = 10;

- /tmp/test.lock file에 먼저 100byte의 “A”로 채우기

- 첫번째 locking영역 10 – 30 byte 구역 을 구조체 flock에 입력 , 공유잠금

- 두번째 locking영역 40 – 50 bytes 구역을 구조체 flock에 입력 , 배타잠금

Kongju national University

Page 25: Memory & Data Management. Linux System Programming Contents 동적 메모리 관리 Memory Allocation Memory De-allocation 파일 잠금 협조형 잠금 공유파일 구역 잠금

Linux System Programming

fcntl() : example code – p3

/* now lock the file */

printf("Process %d locking file\n", getpid());

res = fcntl(file_desc, F_SETLK, &region_1);

if (res == -1) fprintf(stderr, "Failed to lock region 1\n");

res = fcntl(file_desc, F_SETLK, &region_2);

if (res == -1) fprintf(stderr, "Failed to lock region 2\n");

/* and wait for a while */

sleep(60);

printf("Process %d closing file\n", getpid());

close(file_desc);

printf(“\nDone. . .\n”);

}/* main */

Test 방법

예제 프로그램은 lock3.c

reference code로 lock4.c가 있음

두 파일을 compile !

% lock3 &

% lock4

두 프로세스가 경쟁적으로 lock file을 사용

Kongju national University