thread가 깨어 나지를 않습니다...
글쓴이: junteken / 작성시간: 금, 2004/10/22 - 2:54오전
flash get style의 다운로드를 구현하기 위해서 multithread로
socket을 각각열어서 구현할려고 합니다.
다음 소스에서 보면 StartDownLoad를 실행시키면
vector에 들어있는 request들중에 해당되는것을 찾아서
해당 요청을 처리할수있는 waiting상태의 thread를 깨우게 됩니다.
그런데 처음 thread는 잘 깨어나는데 다음 thread는 깨어나지를
않는군요...vector에 들어있는 request목록에서 찾아서
signal도 보내는거는 같은데요...
흠...무슨 문제일까요? 소스가 길어서 죄송합니다..
int CDownLoadManager::StartDownLoad(string ip) { //ip정보를 가지고 해당ip가 몇번의 쓰레드로 돌아야 할지 //판단하고 그 thread를 waiting상태에서 깨운다. vector<struct UserInfo >:: iterator it= m_ReqInfo.usrinfo.begin(); #ifdef DEBUG fprintf(stderr,"요청 목록 size %d File %s LINE %d\n", m_ReqInfo.usrinfo.size(), __FILE__, __LINE__); #endif for( ; it< m_ReqInfo.usrinfo.end(); it++){ if(!(*it).destIP.find(ip.c_str())){ #ifdef DEBUG fprintf(stderr,"요청 목록에서 %d 번 쓰레드찾음l!!! File %s LINE %d\n", (*it).mynum, __FILE__, __LINE__); #endif pthread_cond_signal(&m_ptrThreadCond[(*it).mynum]); m_ReqInfo.usrinfo.erase(it); return 1; } } return 0; } void *CDownLoadManager::DownLoadThread(void *arg) { #ifdef DEBUG fprintf(stderr,"다운로드 쓰레드 시작l!!! File %s LINE %d\n", __FILE__, __LINE__); #endif int soc, readlen=0; struct sockaddr_in serv_addr; char BUFF[FREAD_SIZE]; CDownLoadManager *temp= reinterpret_cast<CDownLoadManager *>(arg); //소켓생성 if( (soc= socket(AF_INET, SOCK_STREAM, 0)) <0){ fprintf(stderr,"socket creation error File %s LINE %d\n", __FILE__, __LINE__); std::exit(0); } //쓰레드 동기화용 조건 변수 pthread_mutex_lock(&(temp->m_MutexMain)); int mynum= temp->m_nNumber; struct UserInfo usrinfo= temp->m_ReqInfo.usrinfo[mynum]; pthread_cond_signal(&(temp->m_Async));//다음 thread가 생성될수 //있도록 main thread에게 signal을 보냄 pthread_mutex_unlock(&(temp->m_MutexMain)); //socket에 관련된 셋팅 memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family= AF_INET; serv_addr.sin_addr.s_addr= inet_addr(usrinfo.destIP.c_str()); serv_addr.sin_port= htons(usrinfo.port); #ifdef DEBUG fprintf(stderr,"%d 번 쓰레드 기다리는 중l!!! File %s LINE %d\n",mynum, __FILE__, __LINE__); #endif //connect하기전에 waiting상태로 둔다. //StartDownLoad로부터 신호를 기다린다 //신호가 도착하면 쓰레드 전역변수로 부터 //현재 처리해야할 소켓지정값을 가져온다. pthread_cond_wait(&(temp->m_ptrThreadCond[mynum]), &(temp->m_MutexChild)); #ifdef DEBUG fprintf(stderr,"%d 번 쓰레드 깨어남l!!! File %s LINE %d\n",mynum, __FILE__, __LINE__); #endif //connect후에 m_ptrFP에 쓴다. if(connect(soc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0){ fprintf(stderr,"connectio error File %s LINE %d\n", __FILE__, __LINE__); std::exit(0); } //파일에 쓰기전에 file pointer를 원하는 위치에 옮겨주어야 한다. fseek(temp->m_ptrFP, usrinfo.startP, SEEK_SET); #ifdef DEBUG fprintf(stderr,"파일 포인터 옮김l!!! File %s LINE %d\n", __FILE__, __LINE__); #endif //먼저 읽어들인다. //소켓을 계속 읽다가 readlen이 0보다 큰시점에 다음 조건문으로들어간다. //이렇게 해두는 이유는 소켓을 연결하자마자 읽었을때 //데이터가 안올경우도 있을거 같기때문이다. while(1){ readlen= read(soc, BUFF, FREAD_SIZE); if(readlen> 0){ fwrite( BUFF, sizeof(char), readlen, temp->m_ptrFP); #ifdef DEBUG fprintf(stderr,"파일 수신중l!!! File %s LINE %d\n", __FILE__, __LINE__); #endif while(readlen>0){ readlen= read(soc, BUFF, FREAD_SIZE); fwrite(BUFF, sizeof(char), readlen, temp->m_ptrFP); } //일단 한번 읽어들였다면 이제 파일 송신을 끝내도 된다는 말이다. break; } } #ifdef DEBUG fprintf(stderr,"파일 수신완료l!!! File %s LINE %d\n", __FILE__, __LINE__); #endif //모든 resource 반환하는 코드가 들어가야한다. close(soc); //파일 다운로드 진행상황을 갯수단위로 보여줄때는 //여기에 그런 일을 하는 코드가 들어가주면 된다. }
Forums:
댓글 달기