일반적으로 프로세스를 종료할 때 return문을 사용합니다. 그리고 exit()함수를 사용하기도 합니다.
return 문과 exit() 함수를 사용하는 것은 시스템 입장에서 보았을 때 동일합니다.
#include <stdlib.h>
void exit(int status);
int main()
{
printf("This is test code\n");
return 0; // exit(0);과 동일
}
exit() 함수 외에도 _exit() 함수와 _Exit() 함수가 있습니다. 이 둘 함수가 exit() 함수와 다른점은 exit()함수는 atexit() 함수로 등록한 종료 핸들러가 있다면 이 핸들러를 모두 처리하고, 표준 입출력 스트림을 닫는 작업을 수행한 후 커널의 종료 작업을 실행하지만 _exit(), _Exit() 함수는 바로 커널에서 종료작업을 실행한다는 것입니다.
커널 종료 작업이라고 하면 프로세스가 사용하던 메모리를 해제하고 열어놓았던 파일의 descriptor등 을 닫는 작업 등 을 말합니다.
유닉스 계열 시스템에서 _exit() 함수와 _Exit() 함수는 같은 함수라고 생각해도 좋습니다.
#include <stdlib.h>
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
return문을 사용하던 exit(), _exit(), _Exit() 함수를 사용하던 프로세스의 종료 상태를 함수의 인자로 지정하게 됩니다.
이 인자는 종료 상태를 부모 프로세스에게 알려줄 수 있는 값입니다.
아래 예제에서 사용된 exit() 함수에 들어 있는 인자 -1과 0 값은 부모 프로세스에게 종료 상태를 알려줄 수 있는 값이 됩니다.
부모 프로세스는 자식 프로세스의 종료 상태 값을 얻어서 자식 프로세스가 어떤 상태로 종료 되었는지를 알 수 있는 것입니다.
#include <stdio.h>
#include <stdlib.h>
float divide(int a, int b)
{
if(b == 0) {
return -1; // 0으로 나누는 것은 에러!
}
return a/b;
}
int main()
{
float ret = 0;
ret = divide(10,5);
if(ret == -1) {
printf("Error!\n");
exit(-1); // 0으로 나누기 시도
}
printf("ret : = %f\n", ret);
ret = divide(10,0);
if(ret == -1) {
printf("Error!\n");
exit(-1); // 0으로 나누기 시도
}
printf("ret : = %f\n", ret);
exit(0);
}
하지만 자식 프로세스가 비정상적으로 종료되었을 경우에는 커널에서 비정상 종료 상태를 별도로 설정하게 됩니다.
부모 프로세스는 자식의 종료 상태(정상/비정상)를 wait() 함수 또는 waitpid() 함수로 얻을 수 있습니다.
wait() 함수 포스팅에서 자식 프로세스가 정상/비정상적으로 종료되었을 때 부모 프로세스가 어떻게 상태를 얻어 오는지 좀더 자세히 살펴 보도록 하겠습니다.
아래와 같이 간단하게 완성이 되었습니다. 각 버튼을 눌렀을 때 Internal/External Storage 에 저장하고, Print 버튼을 눌렀을 때 저장된 내용이 출력되도록 한 예제입니다. 작성된 코드는 https://github.com/bettercho/MyGithub/tree/master/storeuserdata 를 참고하세요.
BeautifulSoup 은 HTML 및 XML 파일에서 원하는 데이터를 손쉽게 Parsing 할 수 있는 Python 라이브러리 입니다.
오늘은 Beautiful Soup 라이브러리를 활용하여 HTML 코드 안에서 원하는 Data 를 뽑아내는 예제를 다뤄보려고 합니다.
1. Beautiful Soup 설치하기
Beautiful Soup 라이브러리는 Python 에서 기본적으로 제공하는 라이브러리에 해당하지 않기 때문에 별도의 설치가 필요합니다.
Windows 에서는 cmd 창에서 간단하게 pip 명령으로 설치할 수 있습니다.
- pip install beautifulsoup4
pip 는 Python 설치 디렉토리의 Scripts 폴더 밑에 있기 때문에, 해당 위치로 이동하여 명령어를 실행해 주어야 합니다.
설치가 완료되면 Python 설치 디렉토리 밑의 Lib/site-packages/ 위치에 bs4 디렉토리가 생성된 것을 확인 할 수 있습니다.
2. HTML 에서 원하는 정보 추출하기 예제
먼저 BeautifulSoup 라이브러리 사용을 위해 bs4 를 import 합니다.
frombs4importBeautifulSoup
예제에 사용될 HTML 문서는 다음과 같습니다.
html_doc="""<html><head><title>The Dormouse's story</title></head><body><p class="title"><b>The Dormouse's story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.</p><p class="story">...</p>"""
문서를 Parsing 하기 위해서 BeautifulSoup 생성자에 해당 문서를 인자로 전달 해주어야 합니다.
아래와 같이 문자 열을 전달할 수도 있고, file handle 을 전달 할 수도 있습니다.
그래서 생성한 BeautifulSoup 객체의 find_all 함수를 이용해서 영화 제목이 담긴 div tag 를 가진 항목을 list 로 뽑아 내었습니다.
if __name__ == "__main__":
soup = BeautifulSoup(urllib.request.urlopen('http://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20161120').read(), 'html.parser')
res = soup.find_all('div', 'tit5')
print(res)
위 코드에서 res 를 출력해보면, 의도했던대로 모든 div tag 항목이 저장되어 있는 것을 확인 할 수 있습니다.
위와 같이 1차적으로 Parsing 이 되었고, 완벽하게 영화 제목만 가져오기 위해 다시한번 파싱을 해줍니다.
동일 Tag 로 잘 분리가 되어있다면, get_text() 를 이용해 해당 tag 에서 text 정보면 가져올 수 있습니다.
그래서 최종적으로 완성된 코드는 아래와 같이 간단합니다.
if __name__ == "__main__":
soup = BeautifulSoup(urllib.request.urlopen('http://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20161120').read(), 'html.parser')
res = soup.find_all('div', 'tit5')
for n in res:
print(n.get_text())
결과를 출력해 보면 원하는 데로 제목만 잘 출력이 되었습니다. ^^
결과적으로, 네이버 페이지에 있는 많은 영화 제목들을 단 몇줄로 간단하게 출력해본 예제입니다.
예제는 네이버 페이지이지만, 다양한 사이트에서 원하는 정보를 뽑아낼 때 활용할 수 있겠습니다.
01-06 13:03:14.034 11277-11277/com.example.codetravel.getmainlooper D/MainActivity: changeButtonText method is called from non-main thread
Looper.myLooper() 함수를 로그로 출력하였을 때 내용은 아래와 같습니다.
Looper (main, tid 1) <== 메인 스레드에서 호출
null <== TestThread에서 호출
이것이 의미하는 것을 알기 위해서 Looper 클래스의 toString()함수를 보도록 하겠습니다. (xref : Looper.java)
Looper (" 스레드 이름", "스레드 ID") 임을 알 수 있습니다.
3. 현재 스레드가 Main thread(UI thread)인지 아닌지 검사하고 싶을 경우
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
private TestThread mTestThread;
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.button);
}
public void onClickButton(View view) {
Log.d(TAG,"onClickButton()" + " " + Thread.currentThread() + " " + Looper.getMainLooper().getThread());
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
Log.d(TAG,"onClickButton() : This thread is main thread!");
}
else {
Log.d(TAG,"onClickButton() : This thread is not main thread!");
}
mTestThread = new TestThread();
mTestThread.start();
}
class TestThread extends Thread {
@Override
public void run() {
Log.d(TAG,"TestThread run()" + " " + Thread.currentThread() + " " + Looper.getMainLooper().getThread());
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
Log.d(TAG,"TestThread run() : This thread is main thread!");
}
else {
Log.d(TAG,"TestThread run() : This thread is not main thread!");
}
while(true) { // ps 명령어로 스레드 ID를 보기 위해서 스레드가 종료되지 않도록 하기 위한 코드
// 아무 동작도 안하고 그냥 살아 있는 스레드
}
}
}
}
로그를확인하기전에코드만으로예측해보면 onClickButton() 함수는 UI thread에서호출되기때문에 "This thread is main thread!" 가출력될것이라는것을예측할수있습니다.
그리고 TestThread 스레드가생성되어 run() 함수가동작하는스레드는메인스레드가아닌백그라운드스레드입니다.
이번 포스팅에서는 Kotline 의 기본 제어문(반복문/조건문) 사용법을 알아보도록 하겠습니다.
모든 언어들이 비슷하기 때문에 하나의 언어만 잘 알아두면 나머지 언어의 문법도 금방금방 익힐 수 있는 것 같습니다.
Kotline 의 제어문도 다른 언어들과 비슷 하지만, 함축적으로 사용되는 부분이 있어 다른 언어들과는 다르게 Kotline 의 문법을 모르면 잘 알아보기가 힘들게 되어 있는 부분도 있습니다.
익숙해 지면 다른 언어들보다 편할것이라는 생각도 드네요. ^^
1. If 문
Kotline 에서 if 문은 Expression 입니다. 즉, value 를 return 합니다. if 문 자체로 기존의 3항 연산자의 역할을 대체하기 때문에 더이상 삼항 연산자는 사용되지 않습니다. (조건 ? true : false)
기존 우리는 if 문을 아래와 같이 사용했습니다.
max 에 a 변수를 넣고, 만약 a 보다 b 가 크다면 max 변수에 b 의 값을 넣는 코드입니다.
// Traditional usage varmax=aif (a<b) max=b// With else varmax: Intif (a>b) {
max=a
} else {
max=b
}
Kotline 에서는 위의 if 문을 아래와 같이 간단하게 사용할 수 있습니다.
// As expression valmax=if (a>b) aelseb
즉, " if (a>b) a else b " 구문 자체가 a 혹은 b 의 값을 return 하기 때문에, max 변수에 바로 이 값을 대입할 수 있습니다.
만약, if 문 자체에 블럭이 포함되어야 한다면 위 구문은 아래와 같이 사용할 수 있습니다.
valmax=if (a>b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
위의 경우 블럭의 끝에 쓰여진 값이 return 되는 값이 됩니다.
2. When
When 은 일반 언어에서 사용되던 Switch 문을 대체합니다.
when (x) {
1->print("x == 1")
2->print("x == 2")
else-> { // Note the blockprint("x is neither 1 nor 2")
}
}
When 옆에 쓰여진 x 에 값이, 블럭 안의 조건에 충족이 될 때 까지 모든 인수를 순차적으로 검사 합니다.
아무 조건에도 충족되지 않으면 else 분기문으로 들어가게 되고, Switch 문의 default 문은 필수가 아니지만, When 의 else 문은 필수로 들어가야 합니다.
많은 경우가 동일한 방식으로 처리되어야 하는 경우에는 . (콤마) 를 사용하여 조건을 추가할 수 있습니다.
when (x) {
0, 1->print("x == 0 or x == 1")
else->print("otherwise")
}
각 조건의 경우에는 위와 같이 특정 상수 값 (0, 1) 이 올 수도 있지만, 함수가 올 수도 있습니다.
when (x) {
parseInt(s) ->print("s encodes x")
else->print("s does not encode x")
}
위의 경우에는 x 와 parseInt() 에서 return 되는 값과 일치하게 되면 "s encodes x" 를 출력할 것입니다.
그리고 in 키워드를 사용하여 특정 값의 범위를 지정 할 수도 있습니다.
when (x) {
in1..10->print("x is in the range")
invalidNumbers->print("x is valid")
!in10..20->print("x is outside the range")
else->print("none of the above")
}
in 1..10 은 1<= x <=10 의 범위를 의미 합니다. Range 에 대해서는 'https://kotlinlang.org/docs/reference/ranges.html' 를 참고해 보세요 .
마지막으로 when 을 사용할 때 인수를 생략할 수 있습니다.
인수를 생략하게 되면 분기 조건은 단순히 bool 식이 되고, 해당 조건이 참일 때 분기문이 실행 됩니다.
아래의 경우에서는 x 가 홀수 일 경우 "x is odd", 짝수일 경우 'x is even" 둘다 아닐 경우에 "x is funny" 가 출력 됩니다.
when {
x.isOdd() ->print("x is odd")
x.isEven() ->print("x is even")
else->print("x is funny")
}
3. For Loops
for loop 는 비교적 기존에 사용하던 for 문과 크게 다르지 않습니다. iterator 를 제공하는 모든 것들을 반복할 수 있습니다.
아래 예제에서는 item 에 collection 에 있는 모든 값들이 하나씩 대입이 되면서 반복 하게 됩니다.
for (itemincollection) print(item)
배열이나 리스트를 반복할 경우에 index 를 사용하고 싶다면 indices를 사용 합니다.
for (iinarray.indices) {
print(array[i])
}
혹은 withIndex' fun 을 사용해서 index 와 value 를 return 받아 for문을 돌릴 수도 있습니다.
for ((index, value) inarray.withIndex()) {
println("the element at $index is $value")
}
4. While Loops
while 문과 do.. while 문은 java 와 완전히 동일합니다.
아래의 예제에서 do 블록 안에 정의한 멤버변수 y 는 while 의 조건 식에서 참조할 수 있습니다.
while (x>0) {
x--
}
do {
valy=retrieveData()
} while (y!=null) // y is visible here!
여기까지 Kotline 의 if, when, for, while 제어문 사용법에 대해 간단히 알아보았습니다.
기본 문법이기 때문에 잘 익혀두면 Kotline 으로 코딩하는데 많은 도움이 될 것입니다.