# System_Programming
# 1. LINUX
# 특징
- 서버/클라우드에 많이 사용되는 운영체제
- kernel + shell + system처럼 기본 프로그램만 설치되어있는 리눅스를 사용하면 c언어를 컴파일 하는것도 굉장히 빨라진다. 윈도우에서 네시간 걸리면 compile이 리눅스에서는 10분이면 될 수도 있다.
- UNIX 계열이다.
- 프로그래머 스타일이다.
- plain하게 프로그래밍이 가능하다.
- C언어도 몇가지가 있다.
- ANSI C가 표준인데 리눅스에서 쓸 수 있다.
# History
Linus Torvalds
- 가 유닉스를 기반으로 개발
- 다중 사용자, 다중 작업(시분할 시스템, 멀티 태스킹)을 지원하는 유닉스와 유사
GNU 프로젝트 : GNU is not Unix
유닉스는 여러 회사에서 각자 개발, 소스를 공유하지 않았다.
리차드 스톨만 : 상호협력 문화로 돌아갈 것을 주장하며 GNU 선언문을 발표
유닉스를 대체할 수 있는 공개돼있는 운영체제를 만들자! 그리고 이를 위해 Free Software Foundation 설립과 GNU Public License 규약을 만든다.
GPL : 기술은 공유하고 마음대로 수정 업데이트 가능하다. 그러나 새로 만든 기술은 마찬가지로 GPL을 따라야 한다.
운영체제 커널 개발 시도 : GNU Hurd.
운영체제를 만들기 위해선 만들어야 할 레이어들이 굉장히 많다.
vi
: 유닉스 계열의 에디터. improved 버전은vim
이라고 불린다.라이브러리, 컴파일러, 에디터, 쉘 이런것들을 다 만들어 줘야 유닉스를 대체할 수 있다.
GNU Project X Linux
- 핵심인 커널 개발이 계속 지연된다.
- 이때 리누스 토발즈가 리눅스 커널 소스를 오픈한다.
- 리차트 스톨만의 GNU 프로젝트 산출물과 리눅스OS를 합치게 된다.
- GNU도 열심히 만들었는데 억울하게 다들 리눅스라고만 불러서 스톨만이 슬퍼한다.
# Linux Files
- 모든것은 파일이라는 철학이 있다.
- 모든 인터렉션은 파일 I/O처럼 다루어진다. 외부디바이스도!
- File Namespace
- 윈도우 : A드라이브, C드라이브
- 리눅스 : 전역 네임스페이스
- /media/floppy/
- 파일은 inode 고유값과 자료구조에 의해 주요 정보 관리
# Linux Process
- 리눅스 실행 파일 : ELF(Executable and Linkable format)
- 프로세스의 구조(stack, heap, text, data, bss 등을 정의한다)
- 다양한 시스템 리소스
- 시스템콜 호출을 통해 리소스 처리 관리 가능
- 타이머, 시그널, 파일, 네트워크, 디바이스, IPC
- 시스템콜 호출을 통해 리소스 처리 관리 가능
- 가상 메모리 지원
- 프로세는 pid(프로세스ID) 고유값을 구분. (파일은 inode)
- init 프로세스(첫번째 프로세스)를 기반으로 fork() 시스템콜을 해서 부모자식 관계로 신규 프로세스를 만든다.
# Linux 권한
- 시분할 시스템이여서 다중 사용자 접속이 가능하다.
- 이를 사용자/그룹으로 나누어서 권한을 나눠줄 수 있다.
- root라는 기본 아이디가 있어서 이게 슈퍼관리자다.
- 해커들의 최대 목표는 root관리자를 획득하는 것
- 파일마다 사용자/그룹에 대해
- read, write, execute의 권한을 관리한다.
- 접근 권한 정보는 inode의 자료구조에 저장된다.
# 2. Ubuntu
aws에서 진행
# 3. Shell
# Shell 사용법
- shell : 사용자와 운영체제간 인터페이스
- 사용자의 명령 해석 - 시스템콜 호출 - 커널에 명령
- cli 혹은 gui 가 존재
- 이 중 bash를 배우겠습니다.
# 다중 사용자 지원 명령어
- UNIX는 시분할 시스템을 통해 다중 사용자를 지원한다.
whoami
: 아이디 알기passwd
: id의 패스워드를 바꾼다. aws로 만든 ec2 ubuntu에서는 pw설정이 되어있지 않아서 잘 모르겠다.useradd
: 기본 설정을 자동으로 하지 않는다.adduser
: 기본 설정을 자동으로 한다. 이걸 기본으로 쓴다.- id를 만들면 해당 아이디 디렉토리가 /home/ 밑에 만들어진다. useradd하면 이게 안 만들어지고 기타 설정들도 안 만들어진다. adduser를 해보자. root가 아니면 안된다.
sudo
: root권한으로 실행한다. root 계정으로 로그인 하지 않은 상태에서 가능하다.- 특정 유저들만
sudo
를 사용할 수 있게 설정한다.ubuntu
유저는 사용 가능하다. /etc/sudoers
파일에서 설정 변경 가능- 여기에
- 추가해주면 이제 keith 도 sudo 가능
- 왜 그냥
root
를 안쓰냐?sudo
쓰면서 주의하란 말임.
- 특정 유저들만
/home/user/.bashrc
,/home/user/.profile
: 사용자의 기본 설정이 있다.su
:su root
: 현재 사용자 환경설정 기반(.bashrc, .profile) root로 변경su - root
: 변경 사용자 환경설정 기반 root로 변경
shift v
: 한줄 선택y
복사p
붙여넣기
man ls
: 를 쳐서 옵션들을 볼 수 있다 (manual)cat
: vi를 쓰지 않고 터미널에서 바로 내용을 본다.head
,tail
: cat과 비슷한데 첫 10줄, 끝 10줄만 본다.more
: 한 화면에 꽉 차게만 띄우고 space누를때마다 페이지, 엔터누를때마다 한줄씩 넘길 수 있다.rm
: remove. 조심해야된다. 그냥 삭제됨. 리눅스엔 휴지통이 없다.rm -rf 디렉토리명
: recursive force 로 하위폴더 전부다 삭제
# ls와 파일권한
- 1칸 / 3칸 / 3칸 / 3칸
- 파일이면
-
디렉토리면d
- 소유자 / 그룹 / 공개
- 읽기 / 쓰기 / 실행
# chmod (change mod)
-R
directory
: directory 하위의 모든 파일들에게 설정. r은recursive
# chown (change owner)
- 그룹이 빈경우는 사용자의 default 그룹 적용
- 사용자가 빈경우 사용자의 default 그룹 적용
# Redirection and pipe
# Standard Stream
- command로 실행되는 프로세스는 세가지 stream이 있다.
- stdin : standard input stream
- stdout : standard output stream
- stderr : standard error stream
- 모든 스트림은 plain text로 console에 출력된다.
# redirection
- 표준 스트림의 흐름을 바꿀수 있다.
<
,>
를 사용함- 출력의 방향을 바꿀 수 있다.
- 명령어 표준 출력을 화면이 아니라 파일에 쓰고 싶을때!
ls > files.txt
ls내용을 files.txt에 쓰고 싶다. 파일이 없으면 만들어 준다.ls >> files.txt
현존하는 files.txt의 뒤에 내용을 추가해준다.
# pipe
프로세스간 통신에 씌였던 파이프. 근데 여기선 redir과 연결해서 생각하고 ipc와 연결해서 생각하지 않아도 된다.
한 프로세스의 출력 스트림을 다른 프로세스의 입력 스트림으로 사용할 때
ls | grep files.txt
: ls 명령 출력이 grep 명령 입력스트림으로 들어감grep
: 입력 키워드를 찾는 명령어ls | grep issue
: issue라는 단어가 있는 ls결과를 찾는다.grep -i sometext
식으로 많이 쓰인다.
# foreground and background process
폰 노이만 구조에 의해 실행 파일은 모두 메모리에 우선 올라간다. 코드 이미지 또는 바이너리를 실행파일이라고 하고 실행 중인 프로그램은 프로세스라고 한다.
프로세스에는 다음과 같은 상태 정보가 있다.
- 가상 메모리 및 물리 메모리 정보
- 시스템 리소스 관련 정보
- 스케쥴링 단위
리눅스는 기본적으로 다양한 프로세스가 실행된다 . 유닉스의 철학이 여러 프로그램이 서로 유기적으로 각자의 일을 수행하면서 전체시스템이 동작하도록 하는 모델이기 때문.
# foreground process
- 기본적으로 터미널에서 실행하는 모든 것. 프로세스 수행 종료까지 사용자가 다른 입력을 하지 못한다.
# background process
- 사용자 입력관 상관없이 실행됨.
- 실행하고 뒤에
&
를 붙여주면 백그라운드로 실행되며 백그라운드 job 번호와 PID가 뜬다. - ps를 쳐서 백그라운드에 실행됨을 확인할 수 있다.
# 프로세스 관리 및 제어
ctrl z
: 프로세스를 중단한다.jobs
: bg프로세스들을 보여준다.bg
: 최근에 중단되 bg프로세스를 실행한다.ctrl c
: 프로세스를 죽인다.ps
: 프로세스 상태 확인kill -9 pid
하면 프로세스 죽이기 가능. -9는 force의 뜻kill %jobnumber
해도된다.프로세스 중
웹서버
가 있는데 이런건 24시간 돌아간다. 데몬 중 하나임.
# 리눅스 파일 시스템
모든 것은 파일이다. -unix
- 마우스, 키보드, 마이크 이런것도 전부 파일과 같이 다루어짐
- 모든 자원에 대해 추상화 인터페이스로 파일 인터페이스를 활용한다.
cd /dev
: 에 가면 device들을 볼 수 있다.tty
: 터미널. 가상 파일 시스템 인터페이스를 통해 가상 터미널(가상 디바이스)에 연결돼있다.
# 슈퍼 블록(super block)
- 슈퍼 블록 : 파일시스템에 관한 정보가 있다. 전체 사이즈, 어떤 파일시스템 알고리즘인가?
- 파일이름과 inode는 매핑되어 있다. 프로세스와 pid가 매핑되어 있듯이
# 리눅스 파일 시스템 탐색
# inode
- 리눅스 파일 탐색 (/home/ubuntu/link.txt)
- 각 디렉토리 엔트리(dentry) 탐색
- 엔트리는 해당 디렉토리 파일/디렉토리 정보가 있다.
- '/' dentry 에서 'home'을 찾고, 'home' dentry에서 'ubuntu'를 찾고, 'ubuntu' dentry 에서 link.txt 파일이름에 매핑돼있는 inode를 찾는다.
- Each dentry maps an inode number to a file name and a parent directory.
- 각 디렉토리 엔트리(dentry) 탐색
- home 아래에 내 계정
- media, mnt : 디바이스, 추가 ssd
- etc : 다양한 설정 파일들
- dev : 마우스 / 키보드 / 터미널
- bin, sbin : 쉘 명령어의 실행 파일들. 'PATH'설정 돼 ㅇㅆ음
- boot : 부팅 관련
- var/log : 로그파일들 생김. 서버 쓰면 자주 씀.
# 하드 링크
링크는 유닉스 시스템에만 있는 독특한 기능이다.
cp
명령어 : copycp link.txt link3.txt
: link.txt를 복사해서 link3.txt를 만든다
rm
명령어 : removerm link3.txt
ln
: 하드링크- 윈도우에 바로가기가 있다면 unix에서는 링크가 있다.
ln link.txt hard.txt
를 하게되면hard.txt
가 생긴다.- 카피와 같은가? ㄴㄴ 동일한 inode번호와 데이터를 가지고 있다.
- 카피는 inode가 다른 번호가 생긴다.
- 원본 변경시 링크도 당연히 변경
- 원본 삭제시 링크는 그대로 있다
- 링크도 원본만큼 유효한 포인터이기 때문
# 소프트 링크
ln -s link.txt softlink.txt
: -s를 붙여서 소프트링크를 해준다.- 윈도우의 바로가기와 더 비슷하다
- 소프트링크는 inode 값이 다르다!
- 원본 삭제시 소프트링크는 같이 삭제된다.
- 별도의 inode이며 여기에 저장된 address는 원본파일의 inode이다.
- 하드링크는 원본파일과 동일한 inode
# 특수파일
- 디바이스
- 블록 디바이스 : HDD, CD/DVD처럼 블록/섹터 단위로 데이터 송신, IO 송수신 속도 높다.
- 케릭터 디바이스 : 키보드, 마우스 같은 바이트 단위 데이터. 손수신 속도가 낮다.
# 4. System_Programming
# 시스템콜과 API
# 시스템콜
- 시스템 콜 : 사용자 영역에서 커널 영역으로 들어가는 함수
- 여러 라이브러리(api)로 이뤄져있다.
- 리눅스/유닉스는 c언어로 만들어져 있다.
- how does it work
- cpu가 커널 모드로 바뀜
- instruction code(CPU가 제공)로 인터럽트(0x80)를 일으킨다.
- IDT에서 0x80에 해당하는 함수를 실행. 0x80은 system_call() 이다.
- 함수에서 eax와 ebx 참조
- eax레지스터에 시스템콜 번호
- ebx레지스터에 인자값
- 시스템콜 실행
- 사용자모드로 변경
- c 라이브러리
- 커널도 c언어로 이뤄져있다.
- c 컴파일러
#
# API
응용 프로그램과 분리된 하위 호환 인터페이스
라이브러리
동적 라이브러리
- 바이너리가 이미 만들어져 있어서 사용시 여기에 붙여서 쓴다.
- 실행할때 호출하며 실행파일로 컴파일할때는 같이 컴파일 되지 않는다.
- api는 응용프로그램과 분리되어 있다. 그래서 라이브러리가 따로 업데이트 가능하다. 에러가 날 수도 있겠지만.
정적 라이브러리
대표적 라이브러리
유닉스 C 라이브러리 : libc
- cc : c compiler
리눅스 C 라이브러리 : GNU libc,
gcc : gnu c compiler
aws에는 기본설치가 안 되어 있으므로 설치해주자
sudo apt-get install gcc
1gcc -o test.c test
: 컴파일
# ABI와 표준
# ABI(Application Binary Interface)
함수 실행 방식, 레지스터 활용, 시스템 콜 실행, 라이브러리 링크 방식 등
ABI가 호환되면 재컴파일없이 동작
툴체인(컴파일러를 만드는 프로그램)에서 사용된다.
함수의 인자들을 어떤 레지스터에 넣을 것인가? 같은 것을 정해준다.
# POSIX
- API와 ABI를 표준화하려는 시도가 있었다. (IEEE)
- 리차드 스톨만(자유 소프트웨어 재단)이 POSIX를 표준안으로 제안
# 시스템 프로그래밍과 버전
- 소프트웨어는 계속 업데이트 되지만
- 시스템 레벨단 기술은 70년대부터 꾸준하게 유지가 되고 있다.
- 하위 시스템 레벨을 알고 있는게 중요하다.
# 5. Process Management
# PID
# Basic
- 프로그램 : 바이너리, 코드 이미지, 응용 프로그램, application, 또는 실행 파일
- 프로세스 : 현재 실행중인 프로그램(메모리 적재 + 프로세스 상태PCB)
- 스레드
- 리눅스는 무조건 기본 스레드가 포함된다
- 싱글스레드 : 리눅스는 기본적으로 싱글스레드
- 멀티스레드 : 강제로 여러개 띄운경우
# PID
- 유니크한 pid
- 부호형 16비트 정수값 -> 최대값은 2^15 = 32768
- pid 값 한계 때문에 문제가 발생할 수 있다.
sudo vi /proc/sys/kernel/pid_max
# Process Layer
init process's PID = 1
init 프로세스는 운영체제가 만든다.
ppid
를 통해 부모 프로세스의 pid를 알 수 있다.ps -ef
를 통해 알 수 있다.- e : 시스템 상 모든 프로세스 출력
- f : UID, PID, PPID< CPU, STIME, TTY, TIME, CMD를 출력
# 프로세스와 owner
sudo vi /etc/passwd
: pw뿐만 아니라 uid와 gid도 있다.- 사용자 : 비밀번호(가려짐):uid:gid
sudo vi /etc/shadow
# PID & System Call
getpid()
: pid를 가져온다.getppid()
: ppid를 가져온다.- 둘다 시스템콜을 사용한다.
# Process 생성
- 컴파일시 TEXT, DATA, BSS는 만들어지고 실행시 HEAP, STACK이 만들어진다.
- 프로세스 생성 시
- 전체 메모리 만들어진다
- TEXT, DATA, BSS 부분(이미지)이 업로드 된다
- 실행하면서 HEAP, STACK이 바뀌어 간다.
- 프로세스 계층
- 부모와 자식 프로세스가 있다.
# Fork
동일한 코드, 데이터를 가진 프로세스를 만든다
부모 프로세스는 그대로 살아 있다.
자식 생성 시 Program Counter는 같은 위치
리턴 값이 PID이다.
- PID가 0이면 child
- 아니면 부모여서 실행을 다르게 할 수 있다.
# Exec
- 별도의 새로운 프로세스를 만드는 것이 아니라 현재 공간에 덮어 씌운다.
- 부모 프로세스는 사라진다.
- 새로운 실행 파일!
- BSS, DATA, TEXT 전부 덮어씌워진다.
execl(루트부터의디렉토리, argv[0], argv[1]... , NULL)
execlp
: path가 들어가있어서 풀 디렉토리를 안 쳐도 된다.
execle
: 환경변수를 사용자가 직접 세팅해서 쓴다.execlp
는 기존설정된 path를 사용.
v
가 붙으면 인자를 variable로 넣는다.
# wait
- fork() 함수 호출시 자식프로세스가 종료할때까지 부모 프로세스가 기다림.
- 부모 프로세스가 먼저 죽으며 좀비, 고아 프로세스가 생길 수 있다.
- shell프로그램들은 전형적으로 이러하다.
- fork()로 새로운 프로세스 복사후 execl()쓰는 것이 일반적이다.
- shell자체가 기본적으로 fork를 따고 그 안에서 execl을 돌리는 형태다. wait()가 걸려있어서 꺼지지 않는다.
# copy on wirte
리눅스는 프로세스당 4gb의 가상메모리가 할당된다
3~4gb : 커널 스페이스에 운영체제가 들어간다.
프로세스당 들어갈 필요가 없기 때문에 물리메모리는 동일 영역을 사용한다.
0~3gb : 유저
fork()는 새로운 프로레스 공간 생성 후 기본 프로세스 공간 복사
4gb를 복사하면 프로세스 생성시간이 오래 걸린다.
자식 프로세스 생성시, 부모 프로세스의 페이지를 그대로 사용한다.
읽기가 아닌 쓰기를 할때 이때 페이지를 복사하고 분리한다.
이렇게 프로세스 생성 시간을 줄일 수 있고 페이지 수도 최소화 할 수 있다.
# exit
exit()
시스템콜 : 프로세스 종류- 기본 구조 : 부모에서 fork치고 부모는 wait. 자식은 exec하고 부모로 돌아옴. 그 뒤에 뒷처리 함
- 그렇기 때문에 프로세스 종료상태를 알려주는 exit이 필요하다.
- 보통 비정상 종료를 할때
exit
을 사용한다. - c언어 실행시
- 사실
int main(){}
함수도start
라는 함수 안에 있다.start
는 라이브러로 compile될때 바이너리가 붙여져 있다. - start함수 내부에서 main이 진행되고 return 값이 나오면 main함수는 종료.
- start함수의 남은 부분에서 뒷처리가 실행되고 마지막에 있는 exit이 실행되면서 종료된다
- main함수 안에 exit을 쓰면 거기서 바로 start함수까지 끝나게 된다.
- 사실
return
vsexit
- exit : 즉시 종료
- return : main이라는 함수만 종료
exit(EXIT_SUCCESS)
orexit(0)
exit(EXIT_FAILURE)
orexit(1)
- exit() 시스템콜 내부 동작
- atexit() : 종료시 실행될 함수 등록가능
- IO 스트림 버퍼 삭제(stdin, stdout, stderr)
- 프로세스가 오픈한 파일 모두 종료
- tmpfile()을 통해 생성한 임시 파일 삭제
# 6. IPC
기본적으로 process간에 정보를 주고 받을 수 없어서 나온게 IPC
File을 만들어서 공유하던가
커널 공간을 공유함으로 주고 받을 수 있다.
기법들
- file
- message queue
- shared memory
- pipe
- signal
- semaphore
- socket
ipcs
를 통해 kernel 공간 메모리 확인 가능
# pipe
- 부모 -> 자식. 단방향 통신
- pipe는 커널에 생성된다.
# message queue
- 물리의 커널 영역에 message queue를 만들어서 주고 받는다.
- 양방향 통신이 가능하다.
# shared memory
- message queue는 fifo방식인데 이건 그냥 변수처럼 접근 가능하게 한다.
- 공유메모리 key를 갖고 여러 프로세스가 접근 가능하다.
shmget
: 공유메모리를 생성하는 system callshmat
: 메모리에 매핑shmdt
: 메모리 해제shmctl
: 공유 메모리 삭제
# 7. Signal
ipc기법처럼 쓰일 수 있지만 그것만으로 한정 할 순 없다.
유닉스에서 30년간 이용
커널 또는 프로세스에서 다른 프로세스에 어떤 이벤트가 발생되었는지를 알려주는 기법
ctrl c
도 시그널의 한 예다.ctrl z
프로세스를 백그라운드로 바꾼다. 이것도 시그널이다.kill -l
: 시그널을 다 볼 수 있다.
# 시그널과 프로세스
- 시그널을 순서대로 받아서 대기 시킨다.
- blocked 64bit. 시그널이 64개여서 각각 막는지 안막는지 설정
- sig : 어떤 동작을 처리할지 action에 정의돼있다.
- 순서 :
- 프로세스에 signal 발생 시 : signal 관련 자료구조에 signal이 들어가고
- 프로세스는 각종 시스템콜과 인터럽트에 의해 커널모드로 수시로 바뀐다.
- 사용자모드로 전환하는 시점에 마지막에 하는 일 중 하나가 시그널을 확인하고 실행해야되면 실행한다.
# 8. Shell Script
쉘을 사용해서 프로그래밍
서버작업 및 devops를 위해 필요하다
쉘 명령어에 문법이 추가된 형태
example
situation
서버가 다운됨.
저장공간이 없음.
로그 파일 업데이트가 안되어 프로그램 비정상종료
로그파일 누적이 원인
로그파일 자동 삭제 방법은?
해결
쉘스크립트 생성 및 주기적 실행(cron tab)
기본문법
- 파일로 작성 후 파일을 실행
- 가장 첫 라인은
#!/bin/bash
- 실행 권한이 필요하다.
name.sh
형식이다.#
은 주석 라인- 변수
- 변수명=데이터
# 리스트 변수
리스트 변수를 쓸때는 중괄호를 써줘야 한다.
중괄호를 안쓰면 daemons를 변수로 하고(리스트의첫번째만 인식) [1]을 스트링으로 인식한다. 결과 : httpd[1]
# 사전 정의된 지역 변수
# 연산자
- 백틱 꼭 쓰고
- expr로 연산한다
- 숫자와 기호는 다 한칸씩 띄운다.
- 괄호와 곱하기 앞에는 역슬래시를 써야한다.
# 조건문
if [ 조건 ]
then
명령문
fi
2
3
4
# ping
- IP주소가 서버를 가르킨다.
- 핑은 연결돼있는 컴퓨터가 살아있는지 확인한다.
- 확인 요청을 보내면 살아있으면 응답이 온다.
ping -c 1 192.168.0.1 1> /dev/null
- -c : 한번만 확인해라. 안하면 초당 몇회씩 확인함
- 0 표준입력, 1 표준출력, 2표준에러
$?
: 마지막 결과값
#!/bin/bash
ping -c 1 192.169.0.1 1> /dev/null
if [ $? == 0]
then
echo '핑성공!'
else
echo '핑실패!'
fi
2
3
4
5
6
7
8
9
# for
#!/bin/bash
for database in $(ls)
do
echo $database
done
2
3
4
5
6
# while
# 예제 - 백업하기
#!/bin/bash
if [ -z $1 ]||[ -z $2 ]; then
echo usage: $0 sourcedir targetdir
else
SRCDIR=$1
DSTDIR=$2
BACKUPFILE=backup.$(date +%y%m%d%H%M%S).tar.gz
if [ -d #DSTDIR ]; then
tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR
else
mkdir $DSTDIR
tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR
fi
fi
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 인자로 $1 과 $2 두개를 받는다. 제대로 안오면 사용법만 인쇄
date
라는 함수로 시간 가져온다 : backup.현재시각.tar.gz-d
로 디렉토리가 현재 있는지 없는지 판단한다tar
: 70년대부터 있던 압축명령. 원래는 묶기만 했는데 이제 압축도 한다.- x : 묶음 해제
- c : 파일 묶음
- v : 과정을 화면에 표시
- z : gunzip 사용
- f : 파일 이름 지정
- 주요 옵션
tar -cvzf [압축된 파일 이름] [압축할 파일이나 폴더]
tar -xvzf [압축해제할 이름]
# 예제 - 로그파일 정리하기
- 정책
- 로그파일 2일 이상 -> 압축
- 압축파일 3일 이상 -> 삭제
#!/bin/bash
LOGDIR=/var/log
GZIPDAY=1
DELDAY=2
cd $LOGDIR
echo "cd $LOGDIR"
sudo find . -type f -name '*.log.?' -mtime +$GZIPDAY -exec bash -c "gzip {}" \; 2>
sudo find . -type f -name '*.gz' -mtime +$DELDAY -exec bash -c "rm -f {}" \ 2>
2
3
4
5
6
7
8
9
10
11
find
: 찾기..
: 현재폴더-type f
: 디렉토리가 아닌 파일들만*
: 아무 str?
: 한글자 (참고:정규표현식)-mtime +$GZIPDAY
: 2일 이상된 파일 검색-exec bash -c "명령어1; 명령어2";
: 파일들에 해당 명령어 실행
# 9. Thread
# Thread란?
- 프로세스 내에서 실제로 작업을 수행하는 주체
- 프로세스 안에는 한개 이상의 스레드가 작업을 수행
- 스택과 PC register는 독립적으로 할당된다.
- 커널의 도움 없이 상호 통신 가능. -> 동기화 문제를 해결해야한다.
# Pthread란?
- POSIX Thread
- 저수준 API 100개 함수 제공
- 핵심 라이브러리
- 다른 스레드도 Pthread기반으로 구현
# Pthread 라이브러리
<phtread.h>
헤더파일함수는
pthread_
로 시작그룹
- 스레드 관리 : 생성, 종료, 조인, 디태치
- 동기화 : 뮤텍스 등 동기화 관련 함수
glibc와 분리된 libpthread 라이브러리에 구현되어서 컴파일시 명시해줘야한다.
gcc -pthread test.c -o test
# thread 생성
# thread 종료
보통 잘 안쓴다. 알아서 종료되기 때문.
# thread 조인
특정 thread가 끝날때까지 기다려주는 함수
# thread 디태치
스레드 종료시 즉시 관련 리스소 해제. 조인을 기다리지 않고 종료 즉시 해제.
- 종료 후 상태값으로 후처리를 안하면 디태치, 사용하면 조인.
- detach를 했다고 다음 코드들이 join처럼 기다리지 않고 그대로 실행된다.
# mutex
phthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;
자원을 독점할수 있게 해준다.
# 10. System_Programming Advanced
# 메모리와 mmap
malloc
: heap 영역에 동적 메모리를 생성한다.free
: heap영역의 메모리 해제 가능mmap
: 파일, 메모리, 프로세스가 있다고 생각하자. 프로세스에서 파일을 접근하는건 시간이 굉장히 많이 걸린다. mmap은 파일을 메모리에 매핑하여 미리 올려놓을수 있다. 이러면 시스템콜, 스케쥴러, 인터럽트, dma, 시스템버스 모두 필요 없어서 굉장히 빨라진다.파일 액세스를 줄여서 성능을 높인다. 가상 메모리와 흡사한 메커니즘이다.
장점
- read, write의 반복적 파일 접근 방지
- 파일 처리를 위핸 lseek(느림)를쓰지 않고 포인터 조작으로 탐색 가능
단점
- 페이지 사이즈 단위로 매핑된다(4kb)
- 페이지 사이즈 단위가 정수배가 아니면 한 페이지 정도 낭비한다.
- 페이지 사이즈 단위로 매핑된다(4kb)
int msync(void *start, size_t length, int flags)
- start : mmap() 을 통해 받은 메모리 맵의 주소
- length : 동기화 할 길이
- flags : 비동기, 동기 방식을 정한다. 동기시 블럭 상태로 대기 한다.
int munmap(void *addr)
# stat
inode 정보를 받아온다.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int filedes, struct stat *buf);
2
3
4
5
6
7
- stat : 스테이트
- const : 패스정보
- struct : 스테이트라는 구조체. inode자료구조를 가져온다.
- int : file 디스크립터를 넣는다.