2011-01-04 1 views
3

Cwrite()을 직렬화하여 데이터 손실없이 k 스레드간에 공유되는 소켓에 바이트를 쓸 수 있도록하는 방법이 있습니까? 이 문제에 대한 해결책은 사용자 공간 잠금을 포함하고 확장 성은 어떨까요? 미리 감사드립니다.posix C write() 및 스레드 안전

답변

0

POSIX는 send (2)에서 원 자성 보장을 지정하지 않으므로 mutex를 사용해야 할 가능성이 높습니다. 이러한 직렬화로 인해 확장 성이 떨어집니다.

0

하나의 가능한 접근법은 잠금 메커니즘을 사용하는 것입니다. 모든 스레드는 소켓에 어떤 것을 쓰기 전에 잠금을 기다려야하며 잠금이 완료되면 잠금을 해제해야합니다. 모든 스레드가 정확히 동일한 종류의 메시지를 보내는 경우 수신자 측에서 데이터를 읽는 데 문제가 없지만 다른 스레드가 가능한 다른 정보로 다른 종류의 데이터를 보낼 수 있으면 고유 한 메시지 ID가 있어야합니다 각 종류의 데이터와 관련되어 있으며 스레드 ID를 보내는 것이 더 좋습니다 (필요한 것은 아니지만 작은 문제를 디버깅하는 데 도움이 될 수 있음).

typedef struct my_socket_data_st 
{ 
int msg_id; 
#ifdef __debug_build__ 
    int thread_id; 
#endif 
size_t data_size_in_bytes; 
.... Followed by your data .... 
} my_socket_data_t 

확장 성이 응용 프로그램이 실행 될 수있는 하드웨어 리소스를 포함하여 많은 것들에 따라 달라집니다

당신은 같은 구조를 가질 수있다. 네트워크 응용 프로그램이므로 네트워크 대역폭에 대해서도 고려해야합니다. 소켓을 통해 데이터를 송수신 할 때 OS에서 발생하는 제한 사항은 없지만 (현재는 응용 프로그램에서 무시할 수 있다고 생각합니다.) send을 기반으로 동기 또는 비동기를 고려해야합니다. 귀하의 요구 사항. 또한, 자물쇠를 잡고 있기 때문에 자물쇠 혼잡에 대해서도 생각해야합니다. 잠금이 다른 스레드에 대해 쉽게 사용할 수없는 경우 성능이 크게 저하됩니다.

4

당신의 스레드가 응답을 동 기적으로 기다려야하는지 여부에 따라 올바른 대답이 달라집니다. 그들은 단지 소켓에 메시지를 쓰고 피어가 응답 할 때까지 기다릴 필요가 없다면 가장 좋은 대답은 다른 스레드가 메시지를 저장하는 큐에서 메시지를 쓰는 데 전념하는 단일 스레드를 갖는 것입니다. 그렇게하면 작업자 스레드는 메시지를 대기열에 놓고 다른 작업을 수행 할 수 있습니다.

물론 큐는 뮤텍스로 보호되어야하지만 어느 한 스레드는 큐를 조작하는 동안에 만 잠금을 유지해야합니다 (꽤 짧은 시간이 될 수 있음). 모든 스레드가 소켓에 직접 쓰게하는보다 분명한 대안은 쓰기 작업이 완료되는 동안 각 스레드가 잠금을 유지해야합니다. 쓰기는 시스템 호출이고 잠재적으로 오랜 기간 동안 차단 될 수 있기 때문에 대기열에 항목을 추가하는 것보다 항상 더 길어집니다.

스레드가 메시지에 대한 응답을 필요로하더라도 여전히 유사한 작업을 수행하기 위해 비용을 지불 할 수 있습니다. 블로킹을 막기 위해 읽기 및 쓰기 소켓에 select()과 같은 작업을해야하기 때문에 소켓 서비스 스레드가 더 복잡해지고 메시지를 응답과 일치시키는 방법과 스레드에 알리는 방법이 필요합니다. 그들의 반응이 도착했을 때.