2012-06-27 3 views
1

소켓을 발견 한 이래로 스레딩에 대해 배우는 데 신경 쓰고 싶지 않았기 때문에 비 블로킹 변형을 사용했습니다. 그 이후로 나는 스레딩에 대한 더 많은 경험을 쌓았으며, 나 자신에게 묻기 시작했습니다. 왜 그것을 소켓 용으로 사용했을까요?소켓에 스레딩이 사용되는 이유는 무엇입니까?

스레딩의 큰 전제는 그들이 자신의 데이터 집합에서 작업하는 경우에만 의미가있는 것처럼 보입니다.

if(!hashmap.hasKey("bar")) 
{ 
    dostuff    // <-- meanwhile another thread inserts "bar" into hashmap 
    hashmap[bar] = "foo"; // <-- our premise that the key didn't exist 
         //  (likely to avoid overwriting something) is now invalid 
} 

지금 암호를 원격 IP를 매핑하는 해시 맵을 상상 : 당신은 동일한 데이터 세트 작업을 두 개의 스레드가 있으면, 당신은 다음과 같은 상황이있을 것이다. 내가 어디로 가는지 볼 수있어. 제 말은 확실히 그러한 스레드 상호 작용이 잘못 될 가능성은 매우 적지 만 여전히 존재합니다. 그리고 프로그램을 안전하게 유지하려면 모든 우발적 사건을 설명해야합니다. 단순한 단일 스레드 워크 플로우와 비교할 때 설계에 들어가는 노력이 크게 증가합니다.

별도의 데이터 집합이나 스레딩을 사용하도록 명시 적으로 최적화 된 프로그램에서 스레딩이 얼마나 효과적인지 완전히 볼 수 있습니다. 그러나 프로그래머가 작업하고 안전한 프로그램을 출하하는 것과 관련된 "일반"의 경우, 폴링에 대한 스레딩을 사용할 이유가 없습니다.

"분리 된 스레드"접근법이 매우 널리 퍼져있는 것처럼 보일 수 있습니다. 아마도 나는 뭔가를 간과하고있을 것입니다. 나에게 계몽해라! 컴퓨터에 두 개 이상의 CPU 코어를 가지고 있기 때문에, 당신은 만들고 싶어 :

좋은 이유 : :)

+0

스레드를 사용하면 서버에서 두 가지 다른 연결을 동시에 처리 할 수 ​​있습니다. 그렇지 않으면 순차적으로 처리해야합니다. – Gray

+0

한 번에 하나의 HTTP 요청 만 제공 할 수있는 웹 서버를 상상해보십시오. treading을 사용하면 웹 서버가 더 많은 요청을 동시에 처리 할 수 ​​있습니다. –

+0

예, HTTP와 같은 서비스는 관련성이없는 요청을 더 많이 또는 덜 제공 할 수 있다는 큰 이점이 있습니다. 동일한 데이터 세트를 사용하는 곳에서는 트랜잭션 모델이 내장되어있어 스레드 안전성이 보장되는 데이터베이스를 사용합니다. 그러나 이것은 단지 하나의 응용 프로그램 유형입니다. – cib

답변

4

는 소켓 스레드를 사용하는 일반적인 두 가지 이유는, 하나의 좋은 그다지 좋지 않은 일이 있습니다 추가 코어 사용. 단일 스레드 프로그램은 단일 코어 만 사용할 수 있기 때문에 과중한 작업량으로 인해 하나의 코어가 100 % 고정되고 다른 코어는 사용되지 않고 낭비됩니다.

블로깅 입출력을 사용하여 프로그램의 논리를 단순화하려는 경우 - 특히 부분 읽기 및 부분 쓰기를 피하고 각 소켓의 컨텍스트/상태를 유지하려는 경우 그것이 관련 지어지고있는 thread의 스택 하지만 느린 클라이언트 A가 I/O 호출로 인해 빠른 클라이언트 B의 처리를 차단하고 차단하지 않고 한 번에 여러 클라이언트를 처리 할 수 ​​있기를 원합니다.

두 번째 이유는 그리 그리 좋지 않습니다. 좋은 점은 소켓 당 하나의 쓰레드를 갖는 것이 프로그램의 디자인을 간소화하는 것처럼 보이지만, 실제로는 보통 그것을 복잡하게 만든다. 경쟁 조건 및 교착 상태의 가능성을 가져오고 공유 데이터에 안전하게 액세스하는 것을 어렵게 만듭니다 (언급 한대로). 더욱이, I/O를 막아 버리면 프로그램이 정상적으로 종료되지 못하며 (또는 스레드의 소켓 이외의 다른 곳에서 스레드의 동작에 영향을주는 다른 방법으로) 스레드가 일반적으로 I/O 호출 (아마도 무기한)을 일으킬 수있는 확실한 방법이 없습니다. (신호는 멀티 스레드 프로그램에서 안정적으로 작동하지 않으며 비 블로킹 I/O로 돌아 가면 원하는 단순화 된 프로그램 구조가 손실됨을 의미합니다.)

요컨대, 나는 cib-multithreaded 서버가 될 수 있다는 데 동의합니다. 따라서 여러 코어를 절대적으로 사용해야하는 경우가 아니라면 일반적으로 피해야합니다. 심지어는 안전을 위해 여러 스레드가 아닌 여러 프로세스를 사용하는 것이 좋습니다.

+0

클라이언트 코드가 격리 된 요청/rssponse 인 경우 (즉, 채팅 서버가 아닌 파일에서 웹 페이지를 제공하는 경우) 다른 서버 디자인과 마찬가지로 잘못된 코드를 작성하고 다음에 인종 또는 교착 상태가 발생할 가능성이 있습니다. 아무것도 공유되지 않습니다. 스레드가 명시 적 릴리스가 필요한 항목을 소유하지 않으므로 스레드 종료는 일반적으로 문제가되지 않습니다. 모든 가정 쓰레드의 99.9 %는 OS가 프로세스 종료시 종료되도록 방치 할 수 있습니다. OS는 매우 빈약하고 지저분한 사용자 코드와 달리 모든 상태의 스레드를 멈추는 데 매우 뛰어납니다. –

+0

어쨌든 Windows에서는 그렇습니다. 로드 테스트시 멀티 스레드 및 IOCP 서버에는 지저분한 테스트가 필요하지 않고, 어색하고, 지저분한 버그가있는 스레드 종료 코드가 전혀 없습니다. 나는 나의 서버의 작은 '빨간 십자가'아이콘을 클릭하고 OS는 모든 스레드, 소켓, 버퍼, 풀, 서버가 사용 중이거나 유휴 상태이든, 코어가 없든 또는 아무런 노력없이 플래시를 많이 낭비한다. 16. FUD가 필요하지 않을 때 '깔끔하게 종료되는'문제 때문에 대부분의 문제가 발생합니다. 버그는 실제로 OS가 사용할 수있는 하드웨어 인터 코어 통신없이 스레드 종료를 시도하고 있습니다. –

+0

@MartinJames 나는 모든 요청이 완전히 분리되어 있다면, 스레딩에 대한 눈에 띄는 단점이 없다는 것에 어느 정도 동의한다. – cib

2

스레드의 가장 큰 장점은 누적 지연 시간이 요청을 처리하지 못하게하는 것입니다. 폴링 할 때 루프를 사용하여 상태가 변경된 모든 소켓을 서비스합니다. 소수의 고객에게있어서 이것은별로 눈에 띄지 않지만 상당히 많은 수의 고객을 다룰 때 상당한 지연을 초래할 수 있습니다.

각 트랜잭션이 일부 사전 처리 및 사후 처리 (프로토콜에 따라 처리량이 적거나 BEEP 또는 SOAP의 경우와 같이 상대적으로 중요 할 수 있음)가 필요하다고 가정합니다. 사전 처리/사후 처리 요청을 합친 시간은 보류중인 요청의 백 로그가 될 수 있습니다.

설명의 목적으로, 요청의 전처리, 처리 및 사후 처리 단계가 각각 1 마이크로 초를 소비하므로 총 요청이 완료되는 데 3 마이크로 초가 걸린다 고 가정합니다. 단일 스레드 환경에서 시스템은 수신 요청이 1 초당 334 개 요청을 초과하면 (1 초 내에 수신 된 모든 요청을 처리하는 데 1.002 초가 걸리므로) 초당 0.002 초의 시간이 부족하면 당황 할 것입니다. 그러나 시스템이 스레드를 사용하는 경우 이론적으로는 1 초 안에 수신 된 모든 요청을 완료하는 데 필요한 처리 시간이 0.336 초 * (공유 데이터 액세스의 경우 0.334 + 0.001의 사전 처리 + 0.001의 사후 처리) 만 필요합니다. 기간.

이론적으로 모든 요청을 0.336 초 내에 처리 할 수 ​​있지만 각 요청에 자체 스레드가 있어야합니다. 보다 합리적으로는 사전/사후 처리 시간 (0.668 초)을 요청 횟수만큼 배수하고 구성된 스레드 수로 나누는 것이 더 합리적입니다. 예를 들어 동일한 수신 요청과 처리 시간을 사용하면 이론상 2 개의 스레드가 모든 요청을 0.668 초 (0.668/2 + 0.334), 4 개의 스레드를 0.501 초, 8 개의 스레드를 0.418 초로 완료합니다.

데몬이받는 가장 높은 요청 볼륨이 비교적 적은 경우 논 블로킹 I/O를 사용하는 단일 스레드 구현으로도 충분하지만 가끔씩 대량의 요청이 발생할 것으로 예상되는 경우, 스레드 모델.

필자는 처리량이 비교적 적은 소수의 UNIX 데몬을 작성했으며 단순성을 위해 단일 스레드를 사용했습니다. 그러나 ISP 용 사용자 정의 netflow 수신기를 작성했을 때, 데몬에 대한 스레드 모델을 사용했으며 시스템로드 평균에서 최소 범프로 인터넷 사용량의 피크 시간을 처리 할 수있었습니다.

관련 문제