2011-02-22 6 views
4
int sock, connected, bytes_received, true = 1; 
struct sockaddr_in server_addr, client_addr; 
int sin_size; 

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("Socket"); 
    exit(1); 
} 

if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof (int)) == -1) { 
    perror("Setsockopt"); 
    exit(1); 
} 

server_addr.sin_family = AF_INET; 
server_addr.sin_port = htons(atoi(argv[1])); 
server_addr.sin_addr.s_addr = INADDR_ANY; 
bzero(&(server_addr.sin_zero), 8); 

if (bind(sock, (struct sockaddr *) &server_addr, sizeof (struct sockaddr)) 
     == -1) { 
    perror("Unable to bind"); 
    exit(1); 
} 

if (listen(sock, 5) == -1) { 
    perror("Listen"); 
    exit(1); 
} 

printf("\nTCPServer Waiting for client on port 5003"); 
fflush(stdout); 

while (1) 
{ 
    pthread_t *child = (pthread_t *)malloc(sizeof(pthread_t)); 

    sin_size = sizeof (struct sockaddr_in); 
    connected = accept(sock, (struct sockaddr *) &client_addr, &sin_size); 
    printf("\n I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); 

    pthread_create(child, NULL, interpretMessage, NULL); 
    free(child); 
} 

내 TCP 서버는 포트 5003에서 수신 대기합니다. 연결이 생성되면 thread를 생성하고 interpreterMessage 함수를 실행하려고합니다. 이 문제에 대해 몇 가지 질문이 있습니다 ...멀티 스레드 TCP 서버 C

1) 정확한 위치에서 malloc을 무료로 호출하고 있습니까?

2) pthread_create가 호출 된 후 내 코드가 즉시 "무료 (하위)로 점프합니까?" while 루프의 시작 부분으로 돌아 간다. 5 사람들이 코드 실행이 5 개 스레드를 생성하는 않는 방법 같은 정확한 시간 (에 연결하는 경우

3) 어떻게됩니까?)

답변

6

에 코드를 올바르게 mallocfree,하지만 당신이하고있는 방법을 사용합니까 구현이 필요 이상으로 복잡해집니다. pthread_create 함수는 첫 번째 매개 변수가 가리키는 메모리에 새 스레드의 ID를 쓰는 방식으로 작동합니다. 귀하의 경우에는이 버퍼를 동적으로 할당 한 다음 즉시 해제합니다. 결과적으로 메모리는 while 루프의 한 반복 범위로 범위가 지정됩니다.

while (1) 
{ 
    pthread_t child; 

    /* ... */ 

    pthread_create(&child, NULL, interpretMessage, NULL); 
} 

는 이제 child 루프에 로컬로 범위가, 메모리 관리 :이 당신이 원하는 경우, 당신은 단지 pthread_t 스택 할당 pthread_create로의 포인터를 전달을 해제 아마 더 좋을 것 같아 malloc 또는 free에 전화 할 필요없이 자동으로 처리됩니다.

컨트롤이 free (child)으로 계속되었는지 그리고 pthread_create으로 호출 한 후 루프의 맨 위로 돌아 오는 지에 대한 두 번째 질문은 네, 맞습니다. 두 번째 스레드는 interpretMessage을 실행하여 생성되므로 원래 프로세스가 지연되지만이 시점부터는 제어가 다시 시작될 때 약간의 지연이 발생할 수 있습니다.

마지막 질문에 다섯 명이 모두 정확히 같은 시간에 연결하면 다음 번에 accept으로 전화하면 다음 들어오는 연결에 단일 소켓이 제공됩니다. 즉, OS는 자동으로 들어오는 연결을 순서대로 대기열에 넣고 루프의 반복마다 코드에 연결이 있음을 알리고 소켓을 가져 와서 메시지를 처리 ​​할 스레드를 생성합니다.

코드에서 알게된 것 중 하나는 interpretMessage을 호출하기 위해 스레드를 생성 할 때 함수에 인수를 제공하지 않았기 때문에 각 스레드가 생성 된 방법에 대한 컨텍스트없이 작동합니다. 이게 의도적 이었나요?

+0

안녕하십니까. 답장을 보내 주셔서 감사합니다. interpretMessage 함수에 구조체를 전달 했으므로 구문 분석기의 내용과 다른 사람을 혼동하지 않으므로 단순성을 위해 인수를 제거했습니다. 지금해야 할 일이 무엇인지 이해합니다. 정말 고마워요! – Eddie