- 論壇徽章:
- 0
|
問題如下:調(diào)用時(shí)會(huì)阻塞在localtime中。我是用dbx -a 跟蹤到里面查到的。\r\nint errcall( char *pFile, int iLine, int iDebugType, char *format ,...)\r\n{\r\n va_list sArgv;\r\n FILE *pLog;\r\n\r\n time_t iNow;\r\n struct tm *pTime = NULL;\r\n struct stat SStat;\r\n\r\n char sHead[128];\r\n char sError[2048];\r\n char sTemp[16];\r\n char sDate[10];\r\n char sFileDate[10];\r\n char sTime[10];\r\n char sFileName[125];\r\n\r\n va_start(sArgv, format);\r\n\r\n /* 為DEBUG類型且DEBUG開關(guān)處于關(guān)閉狀態(tài)則忽略該次調(diào)用 */\r\n if (g_iDebugFlag == 0 && iDebugType == 0)\r\n return( 0 );\r\n /* 取當(dāng)前日期時(shí)間 */\r\n time(&iNow);\r\n pTime = localtime(&iNow);\r\n\r\n sprintf( sDate, \"%04d%02d%02d\",\r\n 1900 + pTime->tm_year, pTime->tm_mon + 1, pTime->tm_mday );\r\n\r\n sprintf(sTime, \"%02d%02d%02d\",\r\n pTime->tm_hour, pTime->tm_min, pTime->tm_sec );\r\n\r\n /* 取日期最后四位作為日志文件名后綴 */\r\n memset(sTemp, 0x00, sizeof(sTemp));\r\n memcpy(sTemp, &sDate[4], 4);\r\n /* 按DEBUG類型分別打開Log文件或錯(cuò)誤日志 */\r\n\r\n if ( !iDebugType || iDebugType == 2 )\r\n sprintf( sFileName, \"%s.%s\", g_sLogFile, sTemp );\r\n else\r\n sprintf( sFileName, \"%s.%s\", g_sErrorFile, sTemp );\r\n\r\n /* 判斷日志文件狀態(tài) */\r\n if ( stat( sFileName, &SStat ) < 0 )\r\n if ( errno != ENOENT )\r\n return( -1 );\r\n\r\n /* 取日志文件最后訪問時(shí)間 */\r\n pTime = localtime( &SStat.st_atime );\r\n\r\n sprintf( sFileDate, \"%04d%02d%02d\",\r\n 1900 + pTime->tm_year, pTime->tm_mon + 1, pTime->tm_mday );\r\n\r\n /* 如已過了一個(gè)月則將原同后綴文件覆蓋 */\r\n if ( strcmp( sDate, sFileDate ) )\r\n strcpy( sTemp, \"w\" );\r\n else\r\n strcpy( sTemp, \"a\" );\r\n\r\n if ( ( pLog = fopen( sFileName, sTemp ) ) == NULL )\r\n return( -1 );\r\n\r\n sprintf(sHead, \"[%s:%d] [%s(%d)] date:[%s] time:[%s] log:\\n\", g_sExecNam\r\ne, getpid(), pFile, iLine, sDate, sTime);\r\n\r\n /*sFmt = va_arg( sArgv, char* );*/\r\n vsprintf( sError, format, sArgv );\r\n va_end( sArgv );\r\n fprintf( pLog, \"%s\", sHead );\r\n strcat( sError, \"\\n\" );\r\n fprintf( pLog, \"%s\", sError );\r\n\r\n fclose( pLog );\r\n return( 0 );\r\n}\r\n\r\n我的環(huán)境是AIX5.3L 64位操作系統(tǒng),使用的是Xlc編譯器。\r\n我的程序在運(yùn)行的過程中,有時(shí)會(huì)在這個(gè)函數(shù)localtime()這個(gè)系統(tǒng)\r\n調(diào)用時(shí)發(fā)生阻塞。查詢了好久,一直不能解決。我沒有使用線程編程。\r\n使用的是unix進(jìn)程方式。調(diào)用這個(gè)函數(shù)的函數(shù)如下:\r\n\r\n/*接收一個(gè)新的套接字,從空閑鏈表中拆出一項(xiàng), 加入多路復(fù)用鏈表中 */\r\n\r\nvoid add_tcp_write_fd(LINK **free_hd, LINK **multi_hd, int listen_sock)\r\n{\r\n int newsock;\r\n socklen_t sock_len;\r\n struct sockaddr addr;\r\n char cli_info[CLIENT_INFO_SIZE+1];\r\n char msg[81];\r\n\r\n\r\n sock_len = sizeof(struct sockaddr_in);\r\n newsock = accept(listen_sock, &addr, &sock_len);\r\n if( newsock < 0 ){\r\n tDebug_Debug ( ERROR, \"accept描述字%d失敗[%d].\",\r\n listen_sock, errno );\r\n tDebug_Debug(ERROR, \"errno = %s\", strerror(errno));\r\n return;\r\n }\r\n\r\n sprintf(cli_info, \"%s:%d=>%d\", get_client_ip(newsock), \\\r\n get_client_port(newsock), \\\r\n get_server_port(newsock));\r\n if (!authorized_ip(get_client_ip(newsock))){\r\n tDebug_Debug(ERROR, \"非授權(quán)客戶端%s,禁止連接!\", cli_info );\r\n close(newsock);\r\n return;\r\n }\r\n\r\n tDebug_Debug(ERROR, \"accepted %s socket %d=>%d\", cli_info, listen_sock,\r\nnewsock); /* 問題出現(xiàn)的地方,在這里調(diào)用時(shí)出的問題 */\r\n \r\n /* 控制同一個(gè)IP地址只能最多由N個(gè)連接(短鏈接方式)\r\n 目前暫固定N為4,今后可用配置參數(shù)設(shè)定(但須規(guī)定最多不能超過某個(gè)數(shù)) */\r\n if (check_link_count(newsock, multi_hd) >= 4) {\r\n sprintf(msg, \"該IP(%s)的鏈接數(shù)超限,拒絕本次鏈接(%d)!\",\r\n get_client_ip(newsock), newsock);\r\n /*new_repos(MSG_OTHER, msg, strlen(msg));*/\r\n tDebug_Debug(ERROR, msg);\r\n close(newsock);\r\n check_link(*multi_hd);\r\n return;\r\n }\r\n\r\n /* 若鏈表項(xiàng)已沒有空閑,則拒絕新的鏈接 */\r\n if ( *free_hd == NULL ) {\r\n /* 若鏈表項(xiàng)已沒有空閑,則拒絕新的鏈接 */\r\n if ( *free_hd == NULL ) {\r\n sprintf ( msg, \"已達(dá)最大鏈接資源,拒絕來自%s的鏈接!\",\r\n get_client_ip(newsock));\r\n /*new_repos(MSG_OTHER, msg, strlen(msg));*/\r\n tDebug_Debug ( ERROR, msg );\r\n close(newsock);\r\n return;\r\n }\r\n\r\n if( add_multi_link( newsock, TCP_WR, cli_info, free_hd, multi_hd)<0){\r\n tDebug_Debug ( ERROR, \"增加TCP讀寫描述字至多路復(fù)用鏈表失敗!\" );\r\n close(newsock);\r\n return;\r\n }\r\n return;\r\n}\n\n[ 本帖最后由 shmdhcxy 于 2007-9-19 17:03 編輯 ] |
|