블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday

    ▣ 연결리스트 - step2

    어제 실습했던 step1은 파일을 읽어서 단순히 연결리스트만 만든 것이다.

    step2는 step1의 중첩되는 부분을 for문이나 while문으로 변경하여 작성한다.

    step2 소스보기(icount)

    반복문 for문을 사용하여 중첩되는 부분을 줄여준다. 조건문 if로 icount가 0일 때

    stp_header = stp_node; 명령 수행한다.

    step1과 비교할 때 결과는 바뀐 것은 없다. 다만 긴 소스코드의 중첩된 부분을 반복문을 통해 줄여준 것이다.

    하지만 문제점은 있다. icount라는 변수를 사용하여 동적 할당의 의미를 없게 만든 것이다. 연결리스트가

    50개가 되면 icount < 50이라고 바꾼다. 이렇게 되면 고정된 수만큼의 동적 할당 받게 되고 그러면 동적 할당

    의 의미가 없어지기 때문이다. icount를 사용하고 싶다면 동적 할당이 아닌 고정된 수만큼을 저장하는 배열을

    쓰는 것이 편하다.

     

    다음과 같이 바꿔준다.

    step2 소스보기(while)

    반복문 while을 사용하여 무한반복 시키고 stp_header를 0으로 초기화 시켜준다.

    if문에서 보면 stp_header가 0일 때 stp_header = stp_node; 명령 수행하도록 한다.

    명령을 수행 후에 stp_header는 0이 아닌 stp_node가 가리키는 주소를 가리키게 된다.

    그 이후에 else안의 명령이 계속 수행되어 iret의 값이 0일 때 while문을 빠져 나온다.

    만약에 stp_header의 초기값을 0으로 초기화 하지 않으면 어떻게 될까?

    stp_header의 초기값이 0으로 정해져 있지 않으면 if문을 수행하지 않고 바로 stp_node를

    따라간 주소의 next가 stp_header의 쓰레기 값을 가리키게 된다.

    그래서 결과를 출력하게 되면..

    보기 좋게 세그멘테이션 오류가 발생한다.



    ▣ 연결리스트 – step3

    step2가 step1의 업그레이드 된 버전이라면 step3은 사람을 생각하게 만드는

    연결리스트이다. 삽입할 위치 정하여 정렬하는 소스이다.

    step3 소스보기

     

    기본적으로 하나의 리스트에서 또 다른 리스트가 추가 될 때 앞에 삽입된다.

    step3는 앞에 삽입외에 중간 삽입, 끝에 삽입을 위해 삽입할 위치를 찾아 삽입하고자

    하는 위치에 넣고 원하는 위치에 삽입하므로써 정렬이 되어 출력하도록 하는 것이 목적이다.

    step2의 소스에서 앞에 삽입에 해당하는 소스를 복사하여

    insert함수를 선언하고 붙혀 넣은 후 else안의 명령들을 삭제한다.

     

    a.dat파일은 아래와 같이 저장되어 있다고 가정한다.

    1, 3, 5는 리스트가 만들어져 있고 2를 삽입하기 위해 1과 3사이에 중간 삽입하기 위한 과정을

    일부를 설명하고자 한다. 삽입하고자 할 때는 정렬이 전제 되어야 한다. 사람도 1,3,5라는 번호를 보여 주지

    않고 2를 어디에 삽입해야 할지 모른다. 함수입장에서 리스트의 내용을 알 수 없게 되면 정렬이 불가능해 진다.

    삽입할 위치를 찾기 위해서 stp_header 포인터를 움직이게 되면 뒷 쪽으로 움직인 포인터가

    다시 앞쪽으로 움직일 수 없는 단뱡향 연결리스트의 단점 때문에 앞에 생성된 리스트의

    위치를 알 수 없게 된다.

    그래서 stp_header 대신 삽입할 위치를 찾아줄 구조체 포인터 current 선언해준다.

    포인터 current는 stp_header가 가리키고 있는 주소를 가리키게 된다.

    하지만 current가 찾게 되는 곳은 삽입해야 할 위치의 그 다음 위치를 가리키게 된다. 이전 위치를

    알 수 없게 된다. 그렇게 되면 앞의 삽입과 다르지 않다. 그래서 이전을 뜻하는 구조체 포인터 prev를

    선언해준다.

    포인터 prev는 current가 가리키고 있는 주소를 가리키게 된다.

    while문으로 진입하여 if문이 참인지 거짓인지를 판단한다.

    current가 0이 아니므로 다음 if문의 참 거짓을 판단한다. 참일 경우는 삽입해야 할 위치를 찾았을 때

    거짓인 경우는 삽입해야 할 위치를 찾지 못했을 때이다. 참과 거짓은 유일한 키값인 iNum을 비교하여

    판단하게 된다.

    주민등록번호는 데이터베이스에서 키값이다. 유일하게 자신을 나타낼 수 있는 고유 값인 것이다.

    while문을 다시 수행하게 되면 두번째 if문에 조건에 만족하게 된다. prev와 current사이에서 break가

    발생한다. if문에서 다시 참과 거짓을 판단한다.

    위의 if문이 참이 되기 위해서는 다음과 같은 상황이어야 한다.

    리스트가 하나만 존재할 때이다. if문을 수행하게 되면 아래와 같이 앞에 삽입되고

    else를 수행하게 되면 뒤쪽 삽입이 된다.

    하지만 지금은 1과 3사이에 중간 삽입을 해야 한다.

    중간 삽입이 이루어 진 것을 알 수 있다.



    네트워크

    좀비 프로세스

    좀비 프로세스는 프로세스 종료 후 메모리상에서 사라지지 않은 프로세스를 말한다.

    fork()함수 호출 이후 자식 프로세스가 종료되면서 반환된 값 0을 부모 프로세스가 받지

    못하면 자식 프로세스는 좀비 프로세스가 된다.

    자식 프로세스가 좀비 프로세스가 되지 않기 위해서 부모프로세스가 커널에게 자식 프로세스가 종료될

    때의 반환값을 요청한다. 함수를 요청하는 함수로 wait()함수를 사용한다.

    status : 포인터 status가 가리키는 변수에 자식 프로세스 종료시 리턴하거나 exit 함수 호출시 전달한

               인자 값이 저장됨.

    fork_wait.c 소스보기

    커널이 반환값을 전달 해주면 자식 프로세스는 소멸된다. 하지만 wait()함수는 호출 시점에서 자식 프로

    세스의 종료가 없을 경우에 자식 프로세스가 종료될 때까지 Blocking상태에 빠진다.

    이러한 Blocking상태를 해결하기 위해서 Waitpid()함수를 쓴다.

    pid : 종료 확인을 원하는 자식 프로세스 ID. 임의의 자식 프로세스인 경우 -1 대입.

    status : wait 함수의 status와 같은 역할

    options : sys/wait.h에 정의된 ‘WNOHANG’ 상수를 인자로 전달하게 되면 이미 종료한 자식 프로세스가

                없는 경우 blocking 상태로 가지 않고 바로 리턴함. 이때 waitpid 함수의 리턴 값은 0이 된다.

    하지만 waitpid()함수는 자식 프로세스가 언제 종료될지 몰라 함수를 여러 번 호출해야 한다.

    fork_waitpid.c 소스보기

    그래서 sigaction함수를 사용하여 SIGCHLD가 발생시 부모 프로세스가 자식 프로세스의 리턴 값을 읽도록

    한다. waitpid 함수의 호출 시점은??

    - 자식 프로세스가 종료되는 순간 부모 프로세스가 waitpid 함수를 호출하도록 해야 함

    - 자식 프로세스가 종료된 시점에 발생하는 시그널 SIGCHLD를 이용

    fork_signal.c 소스보기

     


    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함