내가 여기서 "잘못된 일을하고있다"고 두려워한다면, 저를 삭제하고 사과드립니다. 특히, 나는 일부 사람들이 만든 깔끔한 작은 주석을 어떻게 만드는지 알지 못합니다. 그러나이 스레드에 대해 많은 우려 / 관찰이 있습니다.
1) 인기있는 답변 중 하나에서 의사 코드의 주석이 달린 요소
result = query( "select smurfs from some_mushroom" );
// twiddle fingers
go_do_something_with_result( result );
본질적으로 가짜입니다. 스레드가 컴퓨팅하는 경우 엄지 손가락을 돌리지 않고 필요한 작업을 수행하고 있습니다. 반면에 IO가 완료되기를 기다리는 경우 CPU 시간을 사용 하지 않는 경우 커널의 스레드 제어 인프라의 요점은 CPU가 유용한 작업을 찾는 것입니다. 여기서 제안한대로 "엄지 손가락을 돌리는"유일한 방법은 폴링 루프를 만드는 것입니다. 실제 웹 서버를 코딩 한 사람은 아무도 그렇게 할 수 없습니다.
2) "나사는 어렵다", 데이터 공유의 맥락에서만 의미가있다. 독립적 인 웹 요청을 처리 할 때와 같이 본질적으로 독립적 인 스레드가있는 경우 스레딩은 매우 간단합니다. 한 작업을 처리하는 방법의 선형 흐름을 코딩하고 여러 요청을 처리 할 것입니다. 효과적으로 독립적이 될 것입니다. 개인적으로, 나는 대부분의 프로그래머에게 클로저 / 콜백 메커니즘을 배우는 것이 단순히 위에서 아래로 쓰레드 버전을 코딩하는 것보다 더 복잡하다는 것을 모험 할 것이다. (그렇습니다. 스레드간에 통신해야한다면 인생이 정말 빨리 힘들어 지지만 클로저 / 콜백 메커니즘이 실제로 그것을 변경한다는 것을 확신하지 못합니다.이 접근법은 여전히 스레드로 달성 할 수 있기 때문에 옵션을 제한합니다. 어쨌든
3) 지금까지 어느 특정 유형의 컨텍스트 전환이 다른 유형보다 다소 시간이 걸리는 지에 대한 실제 증거는 아무도 제시하지 못했습니다. 멀티 태스킹 커널을 만든 경험 (내장 컨트롤러의 소규모, "실제"OS만큼 멋진 것은 없음)은 이것이 사실이 아니라고 제안합니다.
4) 다른 웹 서버보다 Node가 얼마나 빠른지 보여주기 위해 현재까지 내가 본 모든 삽화에는 끔찍한 결함이 있지만, Node에 대해 확실히 수용 할 수있는 하나의 이점을 간접적으로 설명하는 방식으로 결함이 있습니다. 결코 중요하지 않습니다). 노드는 튜닝이 필요한 것처럼 보이지 않습니다 (실제로는 허가도 허용하지 않음). 스레드 모델이있는 경우 예상로드를 처리하기에 충분한 스레드를 작성해야합니다. 이 작업을 잘못하면 성능이 저하 될 수 있습니다. 스레드가 너무 적 으면 CPU가 유휴 상태이지만 더 많은 요청을 받아들이고 스레드를 너무 많이 만들면 커널 메모리가 낭비되고 Java 환경의 경우 기본 힙 메모리가 낭비됩니다 . 이제 Java의 경우 힙 낭비는 시스템 성능을 향상시키는 첫 번째 최선의 방법입니다. 효율적인 가비지 콜렉션 (현재 G1에 따라 변경 될 수 있지만 배심원이 적어도 2013 년 초 현재 그 시점에있는 것으로 보입니다)이 많은 여분의 힙을 갖는 데 달려 있기 때문입니다. 따라서 문제가 있습니다. 너무 적은 스레드로 조정하십시오. 유휴 CPU와 처리량이 부족하고 너무 많이 조정하여 다른 방식으로 다운됩니다.
5) 노드의 접근 방식이 "설계 상 더 빠르다"는 주장의 논리를 받아들이는 또 다른 방법이 있습니다. 대부분의 스레드 모델은 시간 분할 컨텍스트 스위치 모델을 사용하며,보다 적절한 (값 판단 경고) 및보다 효율적인 (값 판단이 아닌) 선점 모델 위에 계층화됩니다. 이것은 두 가지 이유로 발생합니다. 첫 번째로 대부분의 프로그래머는 우선 순위 선점을 이해하지 못하는 것 같습니다. 두 번째로 Windows 환경에서 스레딩을 배우면 타임 슬라이싱이 마음에 들지 않든간에 있습니다 (물론 첫 번째 요점을 강화합니다) 자바의 첫 번째 버전은 솔라리스 구현과 윈도우 타임 슬라이싱에 우선 순위를 부여했다. 대부분의 프로그래머들은 "스레딩이 솔라리스에서 작동하지 않는다"는 것을 이해하고 불평하지 않았기 때문에 그들은 모델을 모든 곳에서 타임 슬라이스로 변경했습니다). 어쨌든, 요점은 타임 슬라이싱이 추가적이며 잠재적으로 불필요한 컨텍스트 스위치를 생성한다는 것입니다. 모든 컨텍스트 전환에는 CPU 시간이 걸리며 해당 시간은 실제 작업에서 수행 할 수있는 작업에서 효과적으로 제거됩니다. 그러나 타임 스케일링으로 인해 컨텍스트 전환에 투자 한 시간은 꽤 외설적 인 일이 발생하지 않는 한 전체 시간의 아주 작은 비율을 넘어서는 안되며, 그럴 것으로 예상되는 이유가 없습니다. 간단한 웹 서버). 따라서 시간 분할과 관련된 과도한 컨텍스트 전환은 비효율적입니다. 그 시간은 실제 작업에서 수행 할 수있는 작업에서 효과적으로 제거됩니다. 그러나 타임 스케일링으로 인해 컨텍스트 전환에 투자 한 시간은 꽤 외설적 인 일이 발생하지 않는 한 전체 시간의 아주 작은 비율을 넘어서는 안되며, 그럴 것으로 예상되는 이유가 없습니다. 간단한 웹 서버). 따라서 시간 분할과 관련된 과도한 컨텍스트 전환은 비효율적입니다. 그 시간은 실제 작업에서 수행 할 수있는 작업에서 효과적으로 제거됩니다. 그러나 타임 스케일링으로 인해 컨텍스트 전환에 투자 한 시간은 꽤 외설적 인 일이 발생하지 않는 한 전체 시간의 아주 작은 비율을 넘어서는 안되며, 그럴 것으로 예상되는 이유가 없습니다. 간단한 웹 서버). 따라서 시간 분할과 관련된 과도한 컨텍스트 전환은 비효율적입니다.커널 스레드는 일반적으로 btw)이지만 그 차이는 처리량의 몇 퍼센트가 될 것입니다. 노드에 종종 암시되는 성능 요구에 암시되는 정수 요소의 종류는 아닙니다.
어쨌든, 그 모든 것에 대한 사과는 길고 잔인하지만, 나는 지금까지 토론이 아무것도 입증되지 않았으며, 나는이 상황 중 하나에서 누군가의 의견을 기뻐할 것이라고 느낍니다.
a) 왜 노드가 더 나은지에 대한 실제 설명 (위에서 설명한 두 가지 시나리오를 넘어서, 첫 번째 (가난한 조정)) 내가 지금까지 본 모든 테스트에 대한 실제 설명이라고 생각합니다. ], 실제로 그것에 대해 더 많이 생각할수록 방대한 수의 스택에 사용되는 메모리가 중요한지 더 궁금합니다. 현대 스레드의 기본 스택 크기는 상당히 큰 경향이 있지만 메모리는 클로저 기반 이벤트 시스템은 필요한 것입니다)
b) 선택한 스레드 서버에 실제로 공정한 기회를 제공하는 실제 벤치 마크. 적어도 그런 식으로, 나는 주장이 본질적으로 거짓이라고 믿지 말아야한다. 표시된 벤치 마크는 부당합니다.)
건배, 토비
select()
은 스레드 컨텍스트 스왑보다 빠릅니다.