libev 라 이브 러 리 사용법

9118 단어 서버epolllibev
전환 하 다http://www.yeolar.com/note/2012/12/16/libev/
libev 는 고성능 이벤트 순환 라 이브 러 리 로 libevent 라 이브 러 리 보다 성능 이 좋 으 며 epoll 모델 을 기반 으로 한 패키지 입 니 다.Nodejs 는 그것 을 베이스 라 이브 러 리 로 사용 하 는 것 이다.libev 의 공식 문 서 는 여기 있 습 니 다. 문서 가 비교적 깁 니 다.본 고 는 안의 예 를 결합 하여 그것 의 용법 에 대해 간단 한 정 리 를 한다.
Contents
  • 이벤트 순환
  • 관찰 기
  • ev_io
  • ev_timer
  • ev_periodic
  • ev_signal
  • ev_child
  • ev_stat

  • 기타 기능
  • 파 이 썬 바 인 딩
  • 예시
    먼저 공식 적 인 예 부터 시작한다.
    // a single header file is required
    #include <ev.h>
    #include <stdio.h> // for puts
    // every watcher type has its own typedef'd struct
    // with the name ev_TYPE
    ev_io stdin_watcher;
    ev_timer timeout_watcher;
    // all watcher callbacks have a similar signature
    // this callback is called when data is readable on stdin
    static void
    stdin_cb (EV_P_ ev_io *w, int revents)
    {
      puts ("stdin ready");
      // for one-shot events, one must manually stop the watcher
      // with its corresponding stop function.
      ev_io_stop (EV_A_ w);
      // this causes all nested ev_run's to stop iterating
      ev_break (EV_A_ EVBREAK_ALL);
    }
    // another callback, this time for a time-out
    static void
    timeout_cb (EV_P_ ev_timer *w, int revents)
    {
      puts ("timeout");
      // this causes the innermost ev_run to stop iterating
      ev_break (EV_A_ EVBREAK_ONE);
    }
    int
    main (void)
    {
      // use the default event loop unless you have special needs
      struct ev_loop *loop = EV_DEFAULT;
      // initialise an io watcher, then start it
      // this one will watch for stdin to become readable
      ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
      ev_io_start (loop, &stdin_watcher);
      // initialise a timer watcher, then start it
      // simple non-repeating 5.5 second timeout
      ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
      ev_timer_start (loop, &timeout_watcher);
      // now wait for events to arrive
      ev_run (loop, 0);
      // break was called, so exit
      return 0;
    }

    이 예 는 먼저 이벤트 순환 을 만 든 다음 두 개의 이 벤트 를 등 록 했 습 니 다. 표준 입력 이벤트 와 시간 초과 이 벤트 를 읽 습 니 다.터미널 입력 이나 시간 초과 후 이벤트 순환 을 끝 냅 니 다.
    이벤트 순환
    libev 를 사용 하 는 핵심 은 이벤트 순환 입 니 다. ev 를 사용 할 수 있 습 니 다.default_loop 또는 evloop_new 함수 가 순환 을 만 들 거나 EV 를 직접 사용 합 니 다.DEFAULT 매크로, 구별 은 evdefault_loop 에서 만 든 이벤트 순환 은 스 레 드 가 안전 한 것 이 아니 라 evloop_new 가 만 든 이벤트 순환 은 신호 와 하위 프로 세 스 의 관찰 기 를 포착 할 수 없습니다.대부분의 경우 아래 와 같이 사용 할 수 있 습 니 다.
    if (!ev_default_loop (0))
      fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?");

    또는 백 엔 드 를 명확 하 게 선택 하 십시오:
    struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV);
    if (!epoller)
      fatal ("no epoll found here, maybe it hides under your chair");

    동적 분배 순환 이 필요 하 다 면 ev 를 사용 하 는 것 을 권장 합 니 다.loop_new 와 evloop_destroy 。
    하위 프로 세 스 를 만 든 후 이벤트 순환 을 사용 하려 면 하위 프로 세 스에 서 ev 를 호출 해 야 합 니 다.default_fork 또는 evloop_fork 는 백 엔 드 의 커 널 상 태 를 다시 초기 화 합 니 다. 각각 ev 에 대응 합 니 다.default_loop 와 evloop_new 에서 사용 합 니 다.
    ev_run 시작 이벤트 순환.두 번 째 매개 변 수 는 0 일 때 활동 하지 않 은 이벤트 모니터 나 ev 를 호출 할 때 까지 계속 실행 되 고 처 리 됩 니 다.break 。다른 두 개의 수 치 는 EVRUN 이다.NOWAIT 와 EVRUNONCE 。
    ev_break 에서 이벤트 순환 을 뛰 어 넘 습 니 다.두 번 째 매개 변 수 는 EVBREAK 입 니 다.ONE 혹은 EVBREAKALL 에서 가장 안쪽 으로 튀 어 나 온 ev 를 지정 합 니 다.run 또는 모든 포 함 된 evrun 。
    ev_suspend 와 evresume 은 프로그램 이 끊 겼 을 때 이벤트 순환 을 일시 정지 하고 다시 시작 하 는 데 사 용 됩 니 다.
    옵 저 버
    다음은 관찰 기 를 만 듭 니 다. 주로 유형, 트리거 조건, 리 셋 함 수 를 포함 합 니 다.이벤트 순환 에 등록 하고 등록 조건 을 충족 시 킬 때 관찰 기 를 터치 하여 리 셋 함 수 를 호출 합 니 다.
    위의 예 에는 IO 관찰 기와 타이머 관찰 기 가 포함 되 어 있 으 며 주기 적 관찰 기, 신호 관찰 기, 파일 상태 관찰 기 등 도 있다.
    관찰 기 초기 화 및 설정 evinit 와 evTYPE_set, ev 직접 사용 가능TYPE_init 。
    특정 이벤트 순환 에 관찰 기 를 시작 하여 ev 사용TYPE_start 。 ev_TYPE_stop 관찰 기 를 멈 추고 메모 리 를 방출 합 니 다.
    libev 는 관찰 기 를 4 가지 상태 로 나 누 었 습 니 다. 초기 화, 시작 / 활동, 대기, 정지.
    libev 의 관찰 기 는 우선 순위 도 지원 합 니 다.
    서로 다른 유형의 관찰 기 는 상세 하 게 설명 하지 않 고 공식 적 인 예 만 여기에 붙 여 라.
    ev_io
    표준 입력 가 져 오기:
    static void
    stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents)
    {
      ev_io_stop (loop, w);
      .. read from stdin here (or from w->fd) and handle any I/O errors
    }
    ev_io stdin_readable;
    ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);
    ev_io_start (loop, &stdin_readable);

    ev_timer
    60s 를 만 든 후 시작 하 는 타이머:
    static void
    one_minute_cb (struct ev_loop *loop, ev_timer *w, int revents)
    {
      .. one minute over, w is actually stopped right here
    }
    ev_timer mytimer;
    ev_timer_init (&mytimer, one_minute_cb, 60., 0.);
    ev_timer_start (loop, &mytimer);

    10s 시간 초 과 된 시간 초 과 를 만 듭 니 다:
    static void
    timeout_cb (struct ev_loop *loop, ev_timer *w, int revents)
    {
      .. ten seconds without any activity
    }
    ev_timer mytimer;
    ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */
    ev_timer_again (&mytimer); /* start timer */
    ev_run (loop, 0);
    // and in some piece of code that gets executed on any "activity":
    // reset the timeout to start ticking again at 10 seconds
    ev_timer_again (&mytimer);

    ev_periodic
    한 시간 단위 의 주기 타이머 만 들 기:
    static void
    clock_cb (struct ev_loop *loop, ev_periodic *w, int revents)
    {
      ... its now a full hour (UTC, or TAI or whatever your clock follows)
    }
    ev_periodic hourly_tick;
    ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0);
    ev_periodic_start (loop, &hourly_tick);

    또는 사용자 정의 주기 계산 방식:
    #include <math.h>
    static ev_tstamp
    my_scheduler_cb (ev_periodic *w, ev_tstamp now)
    {
      return now + (3600. - fmod (now, 3600.));
    }
    ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb);

    현재 시간 부터 시작 하려 면:
    ev_periodic hourly_tick;
    ev_periodic_init (&hourly_tick, clock_cb,
                      fmod (ev_now (loop), 3600.), 3600., 0);
    ev_periodic_start (loop, &hourly_tick);

    ev_signal
    SIGINT 를 받 았 을 때 정리 하기:
    static void
    sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)
    {
      ev_break (loop, EVBREAK_ALL);
    }
    ev_signal signal_watcher;
    ev_signal_init (&signal_watcher, sigint_cb, SIGINT);
    ev_signal_start (loop, &signal_watcher);

    ev_child
    fork 새 프로 세 스 입 니 다. 프로 세 스 가 끝 날 때 까지 child 프로 세 서 를 설치 합 니 다.
    ev_stat
    ev_child cw;
    static void
    child_cb (EV_P_ ev_child *w, int revents)
    {
      ev_child_stop (EV_A_ w);
      printf ("process %d exited with status %x
    ", w->rpid, w->rstatus); } pid_t pid = fork (); if (pid < 0) // error else if (pid == 0) { // the forked child executes here exit (1); } else { ev_child_init (&cw, child_cb, pid, 0); ev_child_start (EV_DEFAULT_ &cw); }

    / etc / passwd 에 변화 가 있 는 지 모니터링:
    기타 기능
    static void
    passwd_cb (struct ev_loop *loop, ev_stat *w, int revents)
    {
      /* /etc/passwd changed in some way */
      if (w->attr.st_nlink)
        {
          printf ("passwd current size  %ld
    ", (long)w->attr.st_size); printf ("passwd current atime %ld
    ", (long)w->attr.st_mtime); printf ("passwd current mtime %ld
    ", (long)w->attr.st_mtime); } else /* you shalt not abuse printf for puts */ puts ("wow, /etc/passwd is not there, expect problems. " "if this is windows, they already arrived
    "); } ... ev_stat passwd; ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.); ev_stat_start (loop, &passwd);

    libev 는 사용자 정의 관찰 기, 스 레 드 에서 사용 하 는 등 다른 유용 한 기능 도 많이 지원 합 니 다. 공식 문 서 를 보십시오.
    파 이 썬 바 인 딩
    libev 는 C 와 C + + 인 터 페 이 스 를 제공 하고 많은 다른 언어 도 대응 하 는 제3자 인 터 페 이 스 를 제공 합 니 다.
    libev 의 Python 확장 은 pyev 입 니 다. 문서 참조http://packages.python.org/pyev/ 。
    libev 의 기본 기능 은 pyev 에서 기본적으로 대응 하 는 바 인 딩 이 있 습 니 다.
    공식 적 으로 두 가지 예 를 들 어 그 중의 기본 적 인 용법 을 보 여 주 는 예 를 들 어
    import signal
    import pyev
    def sig_cb(watcher, revents):
        print("got SIGINT")
        loop = watcher.loop
        # optional - stop all watchers
        if loop.data:
            print("stopping watchers: {0}".format(loop.data))
            while loop.data:
                loop.data.pop().stop()
        # unloop all nested loop
        print("stopping the loop: {0}".format(loop))
        loop.stop(pyev.EVBREAK_ALL)
    def timer_cb(watcher, revents):
        watcher.data += 1
        print("timer.data: {0}".format(watcher.data))
        print("timer.loop.iteration: {0}".format(watcher.loop.iteration))
        print("timer.loop.now(): {0}".format(watcher.loop.now()))
    if __name__ == "__main__":
        loop = pyev.default_loop()
        # initialise and start a repeating timer
        timer = loop.timer(0, 2, timer_cb, 0)
        timer.start()
        # initialise and start a Signal watcher
        sig = loop.signal(signal.SIGINT, sig_cb)
        sig.start()
        loop.data = [timer, sig] # optional
        # now wait for events to arrive
        loop.start()

    링크:
    http://www.yeolar.com/note/2012/12/16/libev/

    좋은 웹페이지 즐겨찾기