728x90
더보기

「Linux, system call, operating system, asynchronus programming, 비동기 프로그래밍


오늘은 학교 과제하다가 잘 복습해두고픈 내용이 있어서 써본다

Linux system programming 수업에서 요즘 Signal 부분 과제를 하고있다...

오늘 실습한 코드는signal(알람수신자) 과 alarm(알람발신자) 을 사용해서 동기적 프로그래밍하기!

나를 혼란스럽게 했던 내용...
* signal 은 signal 보내는게 아니라 받는 함수다 ㅡㅡ .... 진짜 넘하지않냐....
* 뭐..안넣어도 세상이 워낙 좋아 컴파일이 되긴했지만 alarm 사용을 위해 unistd.h 헤더 포함시켜주기...
*signal인터페이스

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

첫번째 인자 signum 은 MACRO를 사용한다 ( SIGINT, SIGBUS,SIGALRM,SIGTERM 등...)
(man signal 참고*)
두번째 인자는 함수 포인터이다... 위 형식에 맞게 함수를 선언하고 넣어주면 된다.

첫번째 인자에 해당하는 signal 을 받으면 두번째 인자의 함수가 실행된다.
default 동작도 있다(무시, 종료 등..)


흐름은....
1. alram signal 을 받았을 때(alarm 함수를 통해 'SIGALRM' 시그널 보냄) 어떤 동작을 수행할지 변경하기위해
SigAlarmHandler 함수를 만든다.(이 함수가 signal 의 두번째 인자, 함수 포인터로 들어간다)
SigAlarmHandler :
여기에는 점을 하나 찍어주는 코드와
signal을 다시 호출하는 코드가 들어간다.
( 여기에서 또 두번째 인자로 핸들러를 재귀적으로 넣어주는데, 일부 운영체제에서 핸들러는 한 번 수행된 뒤 초기화되기 때문이다...)

2. 최초로 signal 을보낼 setPeriodicAlarm 함수를 선언해준다.
signal함수로 SIGALRM 받았을 시의 Handler를 설정해주고
alarm() 호출! 파라미터는 시간이 들어간다 (unsigned int, 초단위.. )
0이면 pending 중인 모든 알람이 취소된다

3. main 에서 setPeriodic Alarm 을 호출한다...

그러면 다른 동작이 모두 종료될때까지 반복해서 alarm handler 에 등록한 내용이 주기적으로 수행된다.

실습코드

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> static unsigned int AlarmSecs; // 함수 종료시에도 값 유지되는 전역변수 // static : 다른 파일 접근을 막기 위함 // void SigAlarmHandler(int signo) { // 한 번 호출 후 Hanlder 사라지는 OS가 있으므로 // 재귀적으로 재등록 if( signal(SIGALRM, SigAlarmHandler) == SIG_ERR) { perror("signal"); exit(1); } // 다시 알람 시스템 콜 요청 // 전역변수 사용(함수가 사라지므로) alarm(AlarmSecs); /* DO something */ // 버퍼캐시 바로 flush printf("."); fflush(stdout); return; } int SetPeriodicAlarm(unsigned int nsecs) { if( signal(SIGALRM, SigAlarmHandler) == SIG_ERR) { return -1; } // 정상종료 시 -1 return AlarmSecs = nsecs; alarm(nsecs); return 0; } int main() { int i,j; printf("Doing something every one sec.\n"); // 1초마다 정해진 동작 하는 함수(asynchronus) SetPeriodicAlarm(1); //위 알람과 상관없이 자기 일 하는 코드.. // asynchronuos 함을 더 직접적으로 보기 위해 내맘대로 넣어본 yum! for(i = 0;i < 1000000;i++){ if( i%100000 == 0) printf("\nyum!\n"); for(j = 0; j<20000; j++) {} } return 0; } 67,1 Bot


어마어마한루프는... 일부러 시간끌기용으로 넣어보았다 숫자는 별의미없음

수행결과는 이렇게 나왔당


끝!

참고한것 :학교수업자료, 아오키미네로 「모두를위한 리눅스 프로그래밍」, man alarm

728x90
728x90

리눅스 공부하면서... 이해한걸 또 까먹을까봐 내식대로 적어두려함

 

출처는 학교 리눅스 수업 + 모두를 위한 리눅스 프로그래밍(아오키 미네로, 2018) 이다.

 

컴퓨터는 기본적으로 1차원 바이너리를 읽는다.

따라서 모든 데이터는 1차원으로 바뀌어서 흐른다... 이것을 스트림이라고 할 수 있다.

 

프로세스가 하나 생성되면 해당 프로세스에 3개의 스트림이 자동으로 생성되는데,

이것이 표준입력, 표준출력, 표준에러출력이다.

이들은 각각 0,1,2 의 디스크립터(ID같은것?)를 갖는다. 그치만 그걸 유저에게 외우라고 하진않고....!

STDIN_FILENO, STDOUT_FILENO , STDERR_FILENO 라고 매크로를 지정하여뒀으니 이걸 넣어서 인자로 주고받을수있다

 

이것은 컴퓨터의 중요한 개념인 추상화(abstraction)를 내포하고있는데

내 프로세스는 이 표준입력이 파일에서 온건지 키보드로 친건지는 신경쓰지 않고 똑같이 처리할 수 있다.

표준 출력을 내보낼 때도 마찬가지다. 이걸 모니터에 쓰든 다른 프로세스로 전달하든 알바가 아닌것이당......

 

암튼 이 스트림들을 우리는 수많은 입출력이 포함 된 API 를 통해 간접적으로 쓰고있지만

시스템콜로 직접 호출하려면

unistd.h 헤더를 포함하고, read, write를 사용하면 된다.

write 를 쓰려면

문자열(char []) buf 를 선언하고(당연 변수명은 달라도 됨)

write(STDOUT_FILENO, buf, sizedof(Buf)-1);

 

위와같이 하면 된다.

 

buf는 우리가 흔히 '버퍼링 걸린다' 고 할때의 버퍼인데 (이말도 안쓴지 10년넘긴한듯...) 암튼....

저렇게 하면 buf 에 들어있는 문자열이 표준출력으로 나온다! ( 터미널에 찍힘 ) 파이프로 연결해서 다른데로 보낼수도있다..

 

 

해당내용은 위에 언급한 책 64~71 페이지를 읽어보면 더 자세하고 정확하게 나온당......끗!

728x90
728x90

학교 리눅스 수업 과제로
makefile 에 각 줄이 무엇을 의미하는지 주석을 달아 업로드하는 과제가 있었는데
scp를 이용해 업로드를 하려니 저런 오류가 떴다....

결론적으로 나는 포트 옵션을 잘못 넣어서 저렇게 뜬거였음



위 오류가 나는 이유는 크게

1. ㄹㅇ 경로가 없음 > mkdir 명령어로 폴더를 만들어 주도록 하자
2. 명령어 오류 > 아주 단순 오타일수도 있고... 나처럼 옵션을 잘못 넣었을 수도... 나는 포트를 -P 포트번호 이렇게 넣어야하는걸
P- 포트번호 이딴식으로 잘못넣었었다 하하... ㅠㅠ
3. 포트오류 > 내가 실습용으로 이용하는 서버는 22번 포트가 닫혀있어 매번 포트번호를 넣어줘야하는데 가끔 이상한 숫자를 넣곤한닫....하하

결국 내가 성공한 명령어는 아래와 같다

scp -P 포트번호 /home/경로경로/파일이름 유저네임@서버 : /서버내저장할경로/경로/


이렇게 하고 권한 확인을 위한 비밀번호를 넣으니 업로드가 완료되었다!

scp manual 과
참고한 링크를 첨부하며 글 마무리...

728x90
728x90

GUI 없이 File system을 살펴보는것...

지지난학기에 챗봇을 리눅스 서버에 올리면서 해봤는데

그땐 뭐가 뭔지도 모르고 교수님 따라했음...

너무 혼란스럽고 어려웠던 기억이 난다

 

지금 리눅스(우분투)를 깔아두고 GUI로도 보고 명령어로도 보면서 실습하니 이해도 잘 되고 좋은 것 같다...

 

간혹 리눅스 첨써보는 분들이 내 블로그를 보는거같아서..

여기서 잘 쓰일 명령어를 추가해본당..  ($ 는 명령어임을 표현한것으로 타이핑 안해도 된다)

 

$ cd [path]

[path] 자리에 디렉토리명이나 아래 패스 참고해서 경로를 적어넣으면 된다.

갈길이 멀다면(?) 그냥 본인이 사용할 디렉토리에서 커멘드를 실행시키는것이 편하다...

우분투는 디렉토리명을 우클릭하면 terminal 여는 옵션이있다

GUI 없으면뭐... 그냥 성실하게 찾아서 들어가야지...

(윈도우즈도 탐색기 검색창에 cmd 치면 되긴한데 이 포스트는 리눅스명령어이므로....)

 

$ ls

현재 위치의 파일, 디렉토리들 목록을 보여준다

 

그리고 깨알팁.. 탭 누르면 자동완성된다 하하

 

 

1. PATH

/ root direcctory
.. 상위 dir
. 현재 dir(working dir)
~ home dir ( 로그인 시 )

 

2. 절대경로, 상대경로

 

어디서나 같은 경로가 나오면 절대경로

현재 위치기준으로 하면 상대경로!

../dira/dirb

>> 현재 경로에서 하나 위로 가서 dira > dirb 찾아가라는 의미

 

3. System directory

 

리눅스는 다양한 system directory 들을 가진다...

>> https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standards

 

Filesystem Hierarchy Standard - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Linux standard for directory structure The Filesystem Hierarchy Standard (FHS) defines the directory structure and directory contents in Linux distributions.[1] It is maintained by the

en.wikipedia.org

 

 

File 권한은 글이 길어질 것 같아 3편으로...

728x90

+ Recent posts