- 论坛徽章:
- 0
|
问题如下:调用时会阻塞在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开关处于关闭状态则忽略该次调用 */\r\n if (g_iDebugFlag == 0 && iDebugType == 0)\r\n return( 0 );\r\n /* 取当前日期时间 */\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文件或错误日志 */\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 /* 判断日志文件状态 */\r\n if ( stat( sFileName, &SStat ) < 0 )\r\n if ( errno != ENOENT )\r\n return( -1 );\r\n\r\n /* 取日志文件最后访问时间 */\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 /* 如已过了一个月则将原同后缀文件覆盖 */\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我的环境是AIX5.3L 64位操作系统,使用的是Xlc编译器。\r\n我的程序在运行的过程中,有时会在这个函数localtime()这个系统\r\n调用时发生阻塞。查询了好久,一直不能解决。我没有使用线程编程。\r\n使用的是unix进程方式。调用这个函数的函数如下:\r\n\r\n/*接收一个新的套接字,从空闲链表中拆出一项, 加入多路复用链表中 */\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, \"非授权客户端%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); /* 问题出现的地方,在这里调用时出的问题 */\r\n \r\n /* 控制同一个IP地址只能最多由N个连接(短链接方式)\r\n 目前暂固定N为4,今后可用配置参数设定(但须规定最多不能超过某个数) */\r\n if (check_link_count(newsock, multi_hd) >= 4) {\r\n sprintf(msg, \"该IP(%s)的链接数超限,拒绝本次链接(%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 /* 若链表项已没有空闲,则拒绝新的链接 */\r\n if ( *free_hd == NULL ) {\r\n /* 若链表项已没有空闲,则拒绝新的链接 */\r\n if ( *free_hd == NULL ) {\r\n sprintf ( msg, \"已达最大链接资源,拒绝来自%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读写描述字至多路复用链表失败!\" );\r\n close(newsock);\r\n return;\r\n }\r\n return;\r\n}\n\n[ 本帖最后由 shmdhcxy 于 2007-9-19 17:03 编辑 ] |
|