1. 코 루틴의 "차단"과 스레드의 "비 차단"
스레드의 모든 코 루틴은 기본적으로 이전 장의 코드에서 직렬로 실행됩니다 : https://blog.csdn.net/qq_44065088/article/details/109272505
Producer 코 루틴 함수에서 1 초 동안 대기 하도록 poll 함수가 호출되고 Consumer 에서 생산자 신호 를 기다리기 위해 co_cond_timedwait 함수 도 호출되는 것을 볼 수 있습니다. 코 루틴의 관점에서 볼 때 이러한 대기는 동기식 (동기식 ) 및 차단 ( blocking ) 인 것처럼 보이지만 기본 스레드의 관점에서는 비 차단 (비 차단)입니다. 예 : 스레드의 생산자-소비자 모델에서 pthread_cond_wait도 스레드를 차단합니다. 스레드 의 관점에서는 스레드가 차단 된 것처럼 보이지만 커널의 관점에서는 차단되지 않습니다. 커널은 다음을 수행 할 수 있습니다. 다른 스레드를 실행하도록 서둘러 예약하십시오. 동일한 추론 : 코 루틴은 동일합니다. 코 루틴 자체의 경우 차단이 실현되지만 아래 스레드의 경우 다른 코 루틴 기능을 실행하는 데 바쁠 수 있습니다.
커널 차단을 방지하려면 커널에서 제공하는 비 차단 IO 메커니즘에 의존하고 fcntl을 사용하여 소켓 파일 설명자를 nonBlock으로 설정해야합니다. 물론 libco도 매우 신중합니다.이 비 블록 프로세스를 캡슐화하고 "동기 차단"인 것처럼 가장합니다. (co_cond_timedwait ()와 동일). 실제로 go 언어는이 작업을 수행하지만 libco의 위장은 더 철저하고 기만적이므로 눈이 종종 우리를 속일 수 있습니다. Libco는 dlsym 메커니즘을 통해 다양한 네트워크 IO 관련 시스템 호출을 연결하여 사용자가 "동기화" 할 수 있도록합니다. "" 메소드는 읽기, 쓰기, 연결과 같은 함수를 직접 사용하므로 생산자 소비자 코 루틴 함수에서 co_enable_hook_sys () 가 호출되는 것을 볼 수 있습니다 . [ 호출 후 후크 시스템 호출 함수가 켜지고 구현이 필요합니다. 파일 설명자를 noblock으로 설정하십시오. 그렇지 않으면 스레드 차단에 빠집니다. ]
프로세스에 대해 간략히 설명하겠습니다. 소켓 연결이있는 경우 먼저 non-blocking으로 설정 한 다음 코 루틴을 시작하여 링크를 처리하고 코 루틴 호출은이 새로운 연결에서 읽기를 시도합니다. 데이터, 현재 호출 된 읽기가 연결되어 있으므로 눈에 띄지 마십시오 . 네 가지로 작동합니다 .
- 1.이 읽기 (가짜 몽키 킹)는 현재 코 루틴을 타이머에 등록하여 향후 읽기 시간 초과를 처리합니다.
- 2. epoll_ctl ()을 호출하여 현재 실행 환경의 epoll 인스턴스에 자신을 등록합니다. 등록 프로세스의 두 단계 모두 콜백 함수를 지정해야하며, 이는 향후 현재 코 루틴을 "깨우기"하는 데 사용됩니다.
- 3. co_yield_env 함수를 호출하여 CPU 를 포기합니다 .
- 4. 메인 코 루틴 epoll_wait ()가 읽기 작업의 파일 디스크립터를 읽을 수 있음을 알고 있으면 원래 읽기 코 루틴이 등록한 콜백 을 실행하여 깨 웁니다.
2. 메인 코 루틴과 코 루틴의 "스케줄링"
메인 코 루틴 [메인 스레드가 co_create와 같은 함수를 호출하는 것과 같은 이유, 프로세스가 저하됨]
컨슈머 나 프로듀서가 차단되면 CPU 는 메인 코 루틴에 양보 합니다 .. 현재 메인 코 루틴은 무엇을하나요? 주 코 루틴은 co_eventloop () 함수에서 사용 중입니다. 이 co_eventloop ( 이벤트 루프) 에서 "스케줄러"의 핵심 인 이 co_eventloop ()는 실제로 epoll / kqueue 이벤트 루프 (앞서 설명)를 기반으로하므로 코 루틴 스케줄링 과 이벤트 구동 이 밀접하게 연결되어 있습니다. , 따라서 libco 는 네트워크 라이브러리이기 때문에 코 루틴 라이브러리가 아닙니다 . 배경 서버 프로그램에서 모든 논리는 I / O 네트워크의 주위에 회귀한다 , 와 같은 디자인 libco이 가지고 자신의 합리성을.
모두를위한 그림을 그릴 게
고 루틴 1이 블로킹 수율로 인해 CPU를 메인 스레드로 전달하면 이벤트에 의해 구동되어 어떤 고 루틴에 IO 이벤트가 있는지 확인하고 CPU의 실행 능력은 재개시 응답하는 고 루틴으로 전달됩니다. 실행 후 CPU를 yield의 메인 코 루틴으로 되돌립니다 ( 이 프로세스가 반복됨 ).
3. stCoEpoll_t 구조
우리는 타이머가 이벤트 중심 모델의 네트워크 프레임 워크에서 없어서는 안될 기능이라는 것을 알고 있습니다. 네트워크 I / O 타임 아웃, 타이밍 대기 (poll 또는 timedwait )를 포함한 타이밍 작업은 모두 이것에 의존합니다.
일반적으로 타이머 기능을 사용할 때는 먼저 타이머에 타이머 이벤트 (Timer Event)를 등록하고, 타이머 이벤트를 등록 할 때는 향후이 이벤트의 트리거 시간을 지정해야합니다. 트리거 시간에 도달하면 타이머 알림을 받게됩니다.