멀티 스레드 아니고 비동기 가능하다는데
만약 파일 write_async()라는 함수가 있다면
함수 실행 동안 프로그램은 다음줄부터 그 이하로 계속 실행(1)하는거임?
그리고 파일 쓰기가 다 끝나면 누군가가 다시 write_async() 끝났다고 프로그램에 신호를 줄거고
프로그램은 하던걸 다시 이어서 실행해야할텐데 그럼 위에 실행(1)은 어떻게 되는거지?
OS나 하드웨어부터 그런 신호와 처리방식이 구현되어있는거임?
멀티 스레드 아니고 비동기 가능하다는데
만약 파일 write_async()라는 함수가 있다면
함수 실행 동안 프로그램은 다음줄부터 그 이하로 계속 실행(1)하는거임?
그리고 파일 쓰기가 다 끝나면 누군가가 다시 write_async() 끝났다고 프로그램에 신호를 줄거고
프로그램은 하던걸 다시 이어서 실행해야할텐데 그럼 위에 실행(1)은 어떻게 되는거지?
OS나 하드웨어부터 그런 신호와 처리방식이 구현되어있는거임?
ㅇㅇ 인터럽트라고 찾아보셈 - dc App
인터럽트 신호를 프로그램이 받았는데 프로그램이 다른 동작,, 예를들어 반복문 수행중이라면, 어느 시점에 다시 비동기 함수 끝나는 곳으로 복귀하는거임? 그게 아니라면 프로그램은 비동기 대기 상태로 기다리는건가?
나도 자세힌 몰라서 미안 - dc App
프로세스에서 I/O 요청을 OS에게 하면, OS와 디바이스 드라이버가 쿵짝 하면서 처리를 함. 디바이스 드라이버는 디스크, 랜카드 이런 장치들을 다룰 수 있는 소프트웨어라고 보면됨. 디바이스 드라이버가 저 장치들과 통신을 하게되고 디바이스에서 처리가 끝나면 디바이스가 CPU에 인터럽트를 날림. CPU는 인터럽트를 보고, 디바이스 드라이버가 미리 등록한 인터럽트 핸들러를 실행하게 된다
근데 나도 더 자세히 이야기 해보려니까 몬가 헷갈리네
그거 하는동안 프로그램은 뭘하고있음? 만약 다른코드 수행중이라면 이거 수행 다될때까지 IO 완료됐다는 인터럽트를 못받는건가
그거 하는 동안 논블로킹이면 계속 코드 돌고 있고, 블로킹이면 대기상태임 프로세스 상태로 치면 ready -> running -> wait(I/O요청후)
인터럽트 신호받고, 인터럽트 핸들러까지 처리 끝나면 운영체제가 다시 wait인 애를 ready 상태로 만들어서 스케줄링 받을 수 있게하겠지
그럼 블로킹 비동기 함수, 논블로킹 비동기 함수 이렇게 2가지가 있겠네?
이게 언어적으로 다해주니깐 기본적인것에서 의문을 갖는 사람이 있는 문제가 있어
조상님
아 내가 할라그랫는데
자 노드 기준으로 설명 들어간다시스템콜하는 비동기 함수를 호출했을때 그 작업은 커널에서 돌아감커널에서 완료된 작업은 너 말대로 프로그램으로 신호가 감프로그램이 하던걸 다시 실행 < 이 부분이 중요한데, 프로그램의 흐름이랑 코드의 흐름이 다르다는걸 알아야함await write_async(); // 1초 걸린다 가정console.log("done");위와 같이 작성된 단일 파일의 코드가 있다면 이걸 실행하면 마치 1초동안 프로그램이 멈춰있는것처럼 보임실제로 콘솔에는 1초가 지나고 나서야 찍히기도 하고그래서 이게 먼 비동기냐 동기 아니냐 할 수 있음근데 이게 http 서버같은거라면 좀 달라짐
요청이 왓을때 위의 코드 두줄을 실행하도록 만들어 놧다고 가정할게. 첫 요청이 들어왓을때 비동기 함수가 호출되면 노드는 곧바로 두번째 요청의 컨텍스트로 전환되고 두번째 요청에 대해 다시 저 코드를 수행함
씨발 줄바꿈이 왜이래
write_async 는 os에 파일 쓰기 작업을 시작하라고 요청을 보냄. 근데 작업을 시작하기만하고 끝날때까지 기다리진 않는다 그럼 논블락킹 api인거임
끝날때까지 안기다린다는건 파일 쓰기작업이 끝나지도않았는데 write_async 함수가 종료되었고 그 다음줄로 넘어간다는말임
그럼 실제 쓰기 작업이 끝났는지 안끝났는지는 어뜨케확인하냐? 보통 논블록킹 api는 작업 상태를 확인하는 방법을 따로 제공함. 예를들면 write_async는 작업 시작 후 해당 작업을 나타내는 고유 id를 반환함.
나중에 파일 쓰기 작업이 끝난 후 그 결과를 알고싶다면 이 고유한 작업 id를 가지고 운영체제에게 다시 물어보는거임. if(get_task_state(작업id) == completed) get_task_result(작업id) 뭐이런식으로
실제 구현은 운영체제마다 다른 api를 제공함 리눅스는 epoll인데 file descriptor 가 예시에서 말한 작업id역할을 하게됨. 윈도우는 또 다른거 iocp? 잘모르는데 뭐다른거쓰는걸로암
이걸 응용하면 스레드 하나에서 여러 논블락킹 api를 호출할수도 있겠지? for(100) { events[i] = write_async() } 하고 다음 코드 실행하다가 작업결과가 필요한순간이오면 events 배열내용꺼내와서 작업완료되었나 확인하고 완료되었으면 그 결과값을 쓰면될꺼고 완료되지 않았다면 완료될때까지 기다리면됨 무한루프 만들어서
node같은경우에는 런타임에서 비동기작업들을 전부 관리함. 작업이 끝났는지 안끝났는지 노드 내부의 이벤트 루프에서 확인하고, 완료된 작업이 있으면 비동기함수를 호출했을때 같이 넘겨받은 콜백 함수를 실행해주는거임
노드는 콜백 함수를 이벤트큐에 넣어서 메인스레드가 순서대로 처리하는방식으로 처리되고, 닷넷은 내부 스레드풀에서 스레드 하나 가져와서 콜백함수의 코드를 실행하는 방식으로 구현됨. (ui프로그램은 또 다르게 작동하는데 그건 생략..) 닷넷뿐만아니라 코루틴 고루틴 뭐이런놈들은 다 이런식으로 작동할꺼임