2013-06-26 1 views
5

두 스레드가 동시에 같은 함수를 호출하고 함수가 소켓을 통해 텍스트를 보내는 UDP 클라이언트 인 경우 어떻게되는지 궁금합니다.두 개 이상의 pthread가 동일한 함수를 사용하면 어떻게 되나요?

아래 코드를 고려해 볼 때 실행 중이지만 아직 오류가 없습니다. 쓰레드가 같은 소스 (함수, 변수, IP, 포트)를 동시에 사용하고, 소스를 어떻게 공유 하는가에 따라 충돌이 발생했는지 궁금합니다. 나는 아래의 코드가 멀티 쓰레딩의 잘못된 사용이라고 상상할 수있다. 쓰레드가 다른 쓰레드가 사용하지 않는 함수를 사용하도록 쓰레드가 어떻게 사용되어야 하는지를 설명 할 수 있겠는가? 다른 말로하면 어떻게 스레드로부터 안전 할 수 있습니까? 리눅스에 대한 예제 C 코드로

:

void *thread1_fcn(); 
void *thread2_fcn(); 
void msg_send(char *message); 

int main(void){ 
    pthread_t thread1, thread2; 
    pthread_create(&thread1, NULL, thread1_fcn, NULL); 
    pthread_create(&thread2, NULL, thread2_fcn, NULL); 
    while(1){} 
    return 0; 
} 

void *thread1_fcn(){ 
    while(1){ 
     msg_send("hello"); 
     usleep(500); 
    } 
    pthread_exit(NULL); 
} 

void *thread2_fcn(){ 
    while(1){ 
     msg_send("world"); 
     usleep(500); 
    } 
    pthread_exit(NULL); 
} 

void msg_send(char message[]){ 
     struct sockaddr_in si_other; 
     int s=0; 
     char SRV_IP[16] = "192.168.000.002"; 

     s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
     memset((char *) &si_other, 0, sizeof(si_other)); 
     si_other.sin_family = AF_INET; 
     si_other.sin_port = htons(12346); 
     si_other.sin_addr.s_addr = htonl(INADDR_ANY); 
     inet_aton(SRV_IP, &si_other.sin_addr); 
     sendto(s, message, 1000, 0, &si_other, sizeof(si_other)); 
     close(s); 
} 
+2

동일한 기능을 호출하는 데 문제가 없습니다 (각 스레드는 자체 실행 컨텍스트와 스택을 가지고 있습니다). 공유 상태 (라이브러리 호출의 공유 상태 포함)에 액세스하는 데 문제가있을 수 있습니다. 코드를 자체 분석하여 공유 상태가 무엇인지 파악하고이 문제를 해결할 수 있습니다. – user2246674

+1

자동 변수의 장점은 모든 것이 자동으로 작동한다는 것입니다. –

+1

'thread1_fcn()'과'thread12_fcn()'은 여전히'void *'인수를 취하여'pthread_create()'가 기대하는 것과 일치하도록 선언되어야합니다. – jxh

답변

3

만들고 msg_send 내부 소켓을 닫습니다 때문에, 일어날 특별한 아무것도. 모든 것이 잘 작동합니다.

3

코드에 문제가 없습니다. 각 스레드는 동일한 코드를 실행하더라도 별도의 스택을 가지므로 별도의 변수 집합이 작동합니다. 변수는 공유되지 않습니다.

1

스레드가 작은 문자열 리터럴을 message 인수로 전달하지만 함수가 message 기본 주소에서 시작하는 1000 바이트를 보내려고하므로 코드에서 정의되지 않은 동작을 호출합니다.

sendto은 종종 운영체제로의 직접 호출이기 때문에 UDP를 통해 많은 쓰레기를 보내거나 (보안 상 중요한 정보!) 시스템 호출이 범위를 초과하는 메모리 액세스 및 리턴을 감지하거나 -1과 errno는 EFAULT (데이터를 보내지 않았을 가능성이 높음)으로 설정됩니다.

message은 문자열이므로 해당 길이를 계산 한 다음 (null 종결 자의 유무에 관계없이) 귀하에게 달려 있습니다. 수신자는 데이터 그램의 길이에서 Null 종료 문자열을 재구성 할 수 있습니다.)

이 기능은 동시성 문제를 일으키지 않습니다.

sendto 여러 스레드가 동일한 소켓에서이 함수를 호출하는 경우에도 함수가 안전합니다. 그러나 스트림 소켓에서 그렇게하면 예측할 수없는 방식으로 데이터가 바이트 스트림에 인터리브되는 문제가 발생할 가능성이 높습니다.

관련 문제