리눅스에서 돌아가는 thread서버가 SunOS에서 안되네요
글쓴이: bluesound / 작성시간: 일, 2003/11/02 - 1:05오전
간단한 http 서버를 만들고 있습니다.
(사실 학교 프로젝트네요, fork()대신 thread사용하기)
음...전 리눅스에서 잘 바꿔서 만들었구 잘되거든요?
근데 학교 서버에선 안되는군요
리눅스는 레드햇9 이구 학교는 SunOS 5.7 입니다.
안되는 부분은 클라이언트 접속시에 pthread_create()가 -1을 반환하면서
에러가 납니다. ..리눅스에선 되서 안심하구 냈는데...
소스 코드 동봉할테니 도움 부탁드립니다.
에러는 다음과 같습니다.
Thread creation failed: Error 0
제가 pthread_create가 0이 아닌 값을 반환할때 출력하는 메시지 입니다.
#include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<sys/stat.h> #include<fcntl.h> #include<pthread.h> //thread를 사용하기위해 헤더파일 포함 #define LEN (1024*1024) //void http_msg(int); void *http_msg(void *); // http_msg를 phtread_create에 알맞게 조정 int main(int argc, char *argv[]) { struct sockaddr_in server_addr, client_addr; //int server_fd, client_fd; int server_fd, *iptr; //client_fd 를 thread함수에 넘겨주기위해 포인터로 선언 int sin_size; char *http_message; int res; pthread_t a_thread; void *thread_result; /* arguments check */ /* 실행명령어 오류시 에러메시지 출력 */ /* 출력예 usage : 실행파일 포트번호 */ if(argc!=2){ printf("usage : %s port\n", argv[0]); return 1; } /* 소켓 생성 및 오류시 처리 */ if((server_fd=socket(AF_INET, SOCK_STREAM, 0))<0){ perror("socket"); return -1; } /* struct sockaddr_in 구조체의 멤버들에 값 할당 */ bzero((char *)&server_addr, sizeof(server_addr)); /*Same size as struct sockaddr*/ server_addr.sin_family=AF_INET; /*Address family, AF_xxx*/ server_addr.sin_addr.s_addr=htonl(INADDR_ANY); /*Internet address*/ server_addr.sin_port=htons(atoi(argv[1])); /*Port number*/ /* 소켓을 현재 시스템의 포트에 연결 및 오류시 처리 */ if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr))<0){ perror("bind"); return -1; } /* 외부로부터의 접속 대기 및 오류시 처리*/ if(listen(server_fd, 5)<0){ perror("listen"); return -1; } while(1){ /* 연결 수락 및 오류시 처리*/ sin_size=sizeof(struct sockaddr_in); //if((client_fd=accept(server_fd, (struct sockaddr *)&client_addr, &sin_size))<0){ iptr = malloc(sizeof(int)); if((*iptr=accept(server_fd, (struct sockaddr *)&client_addr, &sin_size))<0){ perror("accept"); continue; } printf("Server : got connection from %s\n", inet_ntoa(client_addr.sin_addr)); /* 자식 프로세스를 생성하여 request 처리 - http_msg() 함수 호출*/ //if(!fork()){ // http_msg(client_fd); // close(client_fd); //} // thread 만들기, 클라이언트의 request가 들어오면 쓰레드 만들어 http_msg함수 호출 res = pthread_create(&a_thread, NULL, &http_msg, iptr); if (res!=0){ perror("Thread creation failed"); exit(EXIT_FAILURE); } } close(server_fd); } /* http protocol에 따라 request 처리해주는 루틴 */ //void http_msg(int client_fd) void *http_msg(void *arg) { FILE *fp; char method[10], url[10], version[10]; char buffer[LEN], filename[30]; char *http_header="HTTP/1.1 200 OK\r\nServer : Hanyang Univ. ECE Web Server\r\nContent-type : text/html\r\n\r\n"; int client_fd; client_fd = *((int *) arg); free(arg); pthread_detach(pthread_self()); bzero(buffer, sizeof(buffer)); bzero(method, sizeof(method)); bzero(url, sizeof(url)); bzero(version, sizeof(version)); if((fp=fdopen(client_fd, "r+"))==NULL){ perror("fdopen"); //exit(-1); pthread_exit("fdopen"); // error 시에 thread만 닫음 } fgets(buffer, sizeof(buffer), fp); sscanf(buffer, "%s %s %s\n", &method, &url, &version); printf("file stream = %s\n", buffer); printf("method : %s, url : %s, version : %s\n", method, url, version); if(strcmp(method, "GET")==0){ if(strcmp(url, "/")==0) strcpy(filename, "index.html"); else{ *filename='.'; sprintf(filename+1, url); } printf("filename=%s\n", filename); bzero(buffer, sizeof(buffer)); if((fp=fopen(filename, "r"))==NULL){ perror("fopen"); //exit(-1); pthread_exit("fopen"); // error 시에 thread만 닫음 } if(fread(buffer, 1, sizeof(buffer), fp)==0){ perror("fread"); //exit(-1); pthread_exit("fread"); // error 시에 thread만 닫음 } /* http 헤더와 http 메시지 전송 및 오류시 처리 */ printf("header = \n%s\n", http_header); if(send(client_fd, http_header, sizeof(http_header), 0)<0){ perror("send-header"); //exit(-1); pthread_exit("send-header"); // error 시에 thread만 닫음 } if(send(client_fd, buffer, sizeof(buffer), 0)<0){ perror("send-body"); //exit(-1); pthread_exit("send-body"); // error 시에 thread만 닫음 } } fclose(fp); close(client_fd); pthread_exit("thread has been closed correctly"); }
Forums:
흠...gcc 옵션에 -lsocket -lnsl -lpthread 을 쓰니깐...
pthread_create()가 에러는 안나는군요
근데 제가 올린 소스에서
#define LEN (1024*1024) 부분때문에
Segmentation Fault (core dumped) 라면서 죽네요 (클라이언트 접속시)
100*1024 정도로 줄여주면 제대로 작동을 합니다.
왜 그런가요?
아마도 디폴트 스택량이 부족해서 발생했을 가능성이 많습니다.스레드의
아마도 디폴트 스택량이 부족해서 발생했을 가능성이 많습니다.
스레드의 스택사이즈를 조정해 보시기 바랍니다.
그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.
쓰레드 문제...
확실하지는 않습니다만...
pthread_create 하고 나서 usleep(100)정도 줘 보십시오...
솔라리스에서는 쓰레드 생성후에 바로 실행되는게 아니라
호출한 메인 쓰레드가 종료후에 멀티쓰레드가 도는 걸로 알고 있어서
sleep으로 넘겨주지 않으면 바로 시작되지 않는 걸로 알고 있는데..
가물가물.. ^^;
수고하세요...
Re: 쓰레드 문제...
요즘 posix 쓰레드프로그래밍 책을 보고 있는데 거기에 나와있더군요...
솔라리스 2.5에서는 쓰레드가 시분할되지 않아서 두개 쓰래드를 병렬로 동작하도록 보장하려면 병행 레벨을 2로 높여줘야 한다고....
쓰레드 스택이 오버 플로어 난거 같네요.쓰레드내에.. 있는 buf
쓰레드 스택이 오버 플로어 난거 같네요.
쓰레드내에.. 있는 buffer를 스택에 두지 말고
malloc으로 바꿔서 작업해보세요.
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
댓글 달기