리눅스에서 돌아가는 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로 높여줘야 한다고....
#ifdef sun thr_setconcurrency(2); #endif쓰레드 스택이 오버 플로어 난거 같네요.쓰레드내에.. 있는 buf
쓰레드 스택이 오버 플로어 난거 같네요.
쓰레드내에.. 있는 buffer를 스택에 두지 말고
malloc으로 바꿔서 작업해보세요.
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
댓글 달기