ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • usleep(), signal(), waitpid(), deamon프로세서, Pipeline Architecture
    시스템프로그래밍 - 리눅스 2022. 12. 15. 12:13
    728x90
    반응형

     sleep(), usleep()

     sleep(), usleep()
    ms = 10^-3 밀리세컨
    us = 10^-6 마이크로세컨
    ns = 10^-9 나노세컨


    usleep(50000)일 경우 0.05초


    즉 0.05초단위마다 printf가 출력되는것
    (하지만 I/O 연산 특성상 정확히 0.05초가 지켜질 수 없음)


    단순히 프로그래밍적으로 연산만 수행한다면
    0.05초가 지켜지겠지만 printf를 수행하므로
    0.05초가 지켜지지 못한다는 점을 파악해야함


    그리고 자식쪽에 sleep(5)는 정확하게 5초를 대기하는것

     

     signal() 시스템콜

     signal() 시스템콜
    signal(SIGCHLD, mysig)의 경우는
    이전에 C언어를 학습할 떄 함수포인터를 상기하면 된다.


    int (* signal(int signum, void (*handler)(int)))(int)


    프로토타입을 재 해석하면 아래와 같이 적을 수 있다.


    void (*)(int)를 반환하며
    인자로 int signum과 void (*handler)(int)를 취하는
    함수 signal이라고 적을수 있을 것이다.


    그렇다면 signum과 handler는 무엇일까?
    signum은 signal의 번호가 되며
    handler는 해당하는 signal이 들어왔을 때
    어떤 동작을 취할지
    미리 지침서를 만들어 둔것과 같은 것이다.

     

     wait()와 waitpid()의 차이점

     wait()와 waitpid()의 차이점
     wait()의 경우에는 Blocking으로 동작하며
    waitpid()의 경우에는 Non-Blocking방식으로 동작한다.


    우선 wait()로 구동될 경우 심각한 문제가 되는 것은
    네트워크 상으로 연결된 모든 Client(클라이언트)들은
    1개의 서버에 몇천 몇만개 혹은 그 이상으로 물려 있을 수 있다.
    이뜻은 fork()를 수행한 횟수가 저만큼 된다는 뜻이다.
    즉, 프로세스의 갯수가 저만큼 있는건데
    얘네들이 Context Switching을 수행하면서 동작하는 와중에
    한 녀석에 의해 wait()를 처리하게 되면


    Blocking연산이므로 다른 프로세스들은 CPU를 할당 받지 못한다.
    그러면 당연히 신호를 보내도
    CPU가 이 신호를 받을 시간이 없으므로 신호가 씹힌다.
    이러한 부분을 해결하기 위해 waitpid()를 통해


    Non-Blocking 메커니즘으로 처리를 하면
    어떤 신호든지 즉각즉각 받을수 있기 때문에
    신호가 씹히는 현상을 없앨 수 있다.


    Non-Blocking은 Bloking연산을 하는동안 들어오는 신호를 차례대로 저장해놓고 blocking연산이 끝나면 저장한 신호들을 순서대로 수행하는방식이다.
    Blocking은 저장따윈 없음.

     deamon 프로세서

     deamon 프로세서
     자식이 먼저 죽는 경우외에도
    부모가 먼저 죽는 경우가 있다.




    ls -ef
    TTY-> 터미널
    pts/0 -> 우리가 구동한 터미널
    ?     -> 데몬프로세스


    데몬프로세스는 터미널이 닫혀도 프로세스가 꺼지지 않는다.
    그래서 데몬프로세스는 꺼지지 않아야 하는 프로세스를 돌릴때 사용한다. (서버등)




    pause() -> 현재 프로세스를 대기큐로 빼고 모든 신호를 받을수 있다.
    wait()  -> 자식프로세스의 신호만 받을 수 있다.


    signal(SIGINT, 0)-> SIGINT의 신호로 처리할 함수가 없으므로 커널 원래의 메커니즘을 실행한다.


    signal(SIGINT, SIG_IGN) -> SIG_IGN는 신호를 무시하겠다는 핸들러
    signal(SIGSTOP, SIG_IGN) -> ^z를 막지만 ^z가 먹는다.


    kill -9 pid로 죽일수 있다.(데몬프로세스도 -9로 죽일수 있다.)




    중복루프를 돌다가 데이터오류가 났을때 빠져나올수 있다.

     

     *파이프라인(Pipeline) Architecture

     *파이프라인(Pipeline) Architecture


    기본적으로 모든 프로세서(CPU, GPU, DSP, MCU 전부다)들은 모두 파이프라인이라는 Architecture적인 구조를 가지고 있다.
    (FPGA를 통해 설계되며 프로세서마다 파이프라인이 다른 이유는 FPGA프로그래머가 프로세서를 어떤방향으로 설계 했냐에 따라 갈리게 된다)


    아무튼 가장 단순한 프로세서의 파이프라인을 살펴보자면 동작방식은 아래와 같이 3단계로 구성된다.


    1. Fetch
    2. Decode
    3. Execution


    Fetch는 다음에 실행할 명령어를 미리 물어오는 작업이고
    Decode는 명령어 자체가 2진수로 구성되어 있다보니
    이것을 읽어서 해독해서 어떤 동작을 취해야 하는지 파악하는 과정에 해당하며
    Execution은 최종적으로 CPU가 구동되는 단계를 의미한다.
    또 각각에 1Clock Cycle이 소요된다.


    Intel 계열의 복잡한 프로세서의 경우에는
    60단계까지 존재하는 것도 있다.
    ARM의 경우에는 5단계, 8단계 ~ 9단계등 다양하다.


    DSP나 GPU의 경우엔 파이프라인이 좀 더 복잡하다
    특히 GPU의 경우에는 그래픽 파이프 라인이라고 해서
    엄청난 작업을 수행하는 로직(FPGA Logic)이 들어있다.
    Direct3D를 하면서 그래픽 파이프라인이 뭘 하는지 가볍게 살펴볼 예정이며
    Shader Programming이란 GPU 어셈블리 및 그래픽 파이프 라인을 제어하는 과정이기도 하다.


    중요한 것은 파이프라인은 사실 ILP(Instruction Level Parallelication)을 극대화하기 위한
    메커니즘이었다는 것이다.


    ILP를 극대화하기 위한 방법에는 여러가지 방식이 있다.
    Instruction Scheduling에 기반한 방법,
    OoO(Out-of-Order)라는 비순차 실행 방법,
    그리고 파이프라인 기법 등등이 존재한다.
    파이프라인을 활용하는 이유는 글로 작성할 수 없으니
    이 부분은 그림을 통해 살펴보도록 하자!
    (우선 파이프라인은 기계어 단위로 통과하게 됨)(어셈블리어)


    파이프라인의 단계가 많아질수록 여러명령어들이 병렬처리가 될 수 있다는 뜻이다.
    하지만 단계가 많아질수록 jmp로 인한 파이프라인이 꺠질 때 손실이 많아지게 된다.


    제어문들은 모두 점프가 있다.
    jmp는 파이프라인이 깨지기 때문에 단계가 길면 길수록 성능이 저하된다.
    따라서 goto를 쓰는게 이득.


    goto의 약점 함수를 건너 뛸수없다.


    그래서 
    #include <setjmp.h>
    로 하고
    전역변수로 jmp_buf env;를 만들고


    longjmp(env, 1);로 env로 점프하라는 것이고(강제스택해제시킨다)


    setjmp(env)로 점프가 될 곳을 지정하면서 인수1을 반환한다.
    이것들이 C++의 try-catch이다

     

     

     

     

    부록

    signal(SIGALRM, my_sig);

    SIGALRM 은 알람신호

    alarm(3) 은 3초뒤에 SIGALRM신호를 보낸다 커널로

    kill 이란 명령어나 kill() 시스템콜은 신호를 보내준다.(예전에 죽으라는 신호를 보낼 때부터 만들어졌기 떄문에 이름이 kill이란다)

     

     

    728x90
    반응형

    댓글

Designed by Tistory.