2010-01-27 2 views
4

리눅스에서 두개의 쓰레드가 만들어지고 둘 다 실행 중일 때, 그들 중 하나가 recv()이나 데이터를 사용할 수 없을 때 블록하는 IO syscall을 호출하면, 전체 프로세스는 어떻게 될까요?하나의 스레드가 차단되면 다른 스레드는 어떻게됩니까?

다른 스레드도 차단됩니까?이 문제는 스레딩이 구현되는 방식에 달려 있다고 생각합니다. 스레드 라이브러리가 사용자 공간에 있고 커널이 프로세스 내의 스레드를 완전히 인식하지 못하면 프로세스가 스케줄링 엔티티이므로 두 스레드가 모두 차단됩니다.

또한, 다른 스레드가이 때문에 차단하지 않으면, 그것을 recv 수있는 스레드를 차단 같은 소켓을 통해 데이터 send()? 양면 인쇄?

아이디어가 있으십니까?

답변

1

스레드가 커널 공간 또는 사용자 공간에 구현되어 있는지 여부에 따라 차단 동작이 달라지는 것이 좋습니다. 스레딩이 순전히 사용자 공간에서 구현되는 경우 (즉, 커널이 스레딩에 완전히 관여하지 않는 경우) 커널에 대한 모든 블로킹 엔트리 포인트는 호출 구문에 대한 블로킹 의미를 시뮬레이트 할 수있는 비 블로킹 변형으로 래핑되어야합니다. 스레드 "(예를 들어 AIO를 사용하여 블로킹 대신에/recv 데이터를 보내고 완료 콜백은 스레드를 다시 실행 가능하게 만듭니다).

Linux (및 내가 생각할 수있는 다른 모든 주요 OS)와 커널 수준에서 스레딩이 비슷하거나 커널에 대한 블로킹 호출이 이 아니기 때문에은 다른 모든 스레드를 차단합니다.

예, recv()에서 다른 스레드가 차단 된 소켓에 send()을 연결할 수 있습니다.

+0

감사합니다. 상당히 완전한 대답. 좋은 전화. – Figo

+0

스레드가 recv()를 호출하기 전에 소켓에 ​​데이터가 도착하면 스레드가 실제로 해당 데이터를 가져올 수 있습니까? – Figo

+0

예. 이것이 블로킹되지 않는 데이터 그램 소켓에서 작동 할 수있는 유일한 방법입니다. 제가 도움이 될만한 몇 가지 작은 메모들 - 당신은 이런 종류의 것을 꽤 쉽게 실험 할 수 있습니다. 연결을 '수락'할 잠시 후 잠자기 프로그램을 작성한 다음 새 연결에서'recv'를 호출하십시오.'nc' (netcat) 또는 뭔가를 사용하여 서버에 대한 연결을 만들고 즉시 일부 데이터를 작성하십시오. 서버가 보낸 데이터와 동일한 데이터를 얻게됩니다. 두 번째 메모 -이 질문은 일반적으로 한 번에 한 번에 한 번 질문하는 질문에 대한 세 번째 질문입니다. –

2

한 스레드에서 호출을 차단하면 다른 스레드에 영향을 미치면 안됩니다.

블록 된 통화에 들어가기 전에 차단 된 스레드가 뮤텍스를 잠그고 두 번째 스레드가 동일한 뮤텍스를 잠그려고 할 경우 두 번째 스레드는 차단 호출이 완료 될 때까지 기다릴 필요가 있으며 첫 번째 스레드는 해제해야합니다 자물쇠.

+0

고마워, 그럼 두 번째 질문 : 다른 non-blocking 스레드 recv() 동안 다른 소켓을 차단하는 동안 동일한 소켓을 통해 데이터를 보내려면()? UDP를 가정하십시오. – Figo

2

사용자 공간에 스레드를 구현하여 I/O에서 다른 스레드 블록이 진행되는 동안 하나의 스레드가 계속 진행될 수 있습니다.

차단되지 않은 스레드는 다른 스레드가 스레드를 차단하는 동안 소켓에서 보낼 수 있어야합니다 (필자는 그러한 코드를 작성했습니다).

+0

감사합니다. 좋은 소식입니다. – Figo

+0

syscall이 모든 것을 비 차단 호출을 지원하는 경우에만 가능합니다. 몇 초 동안 fstat와 같은 것으로 모든 사용자 스레드를 정지시킬 수 있습니다. –

+0

@Zan Lynx : 그는 POSIX 호환 aio_read() 및 aio_write() 시스템 호출이있는 Linux에 대해 말하고 있습니다. –

관련 문제