- 论坛徽章:
- 0
|
本帖最后由 weifeng270 于 2012-05-15 16:59 编辑
linux 多线程溢出问题
附件是
valgrind --leak-check=full -v --show-reachable=yes --log-file=/opt/oracle/new/DeviceServer/log/DeviceRegistServer.log ./DeviceRegistServer
的日志
现象是隔一段时间。内存就涨132K
int main(int argc, char* argv[])
{
if(argc < 3)
{
printf("Usage: DeviceRegistServer -p Port(Default port 40005)\n");
printf(" eg: DeviceRegistServer -p 30000\n");
}
int port = 50005; //服务器监听端口号
int arginc = 1; //指针索引
if(argc >= 3)
{
if(argv[arginc][0]=='-' && (argv[arginc][1]=='p'))
{
++arginc;
port = atoi(argv[arginc++]);
}
}
// 创建一个Server socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == SOCKET_ERROR)
{
printf("create sock error.%s \n",strerror(errno));
return 1;
}
sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons((u_short)port);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
printf("bind sock error\n");
return 1;
}
if (listen(sock, BACKLOG_SIZE) == SOCKET_ERROR)
{
printf("listen sock error\n");
return 1;
}
sockaddr_in their_addr;
int sin_size = 0;
sin_size = sizeof(struct sockaddr_in);
// 等待客户端连接
int loopcount=1;
//while(loopcount<10000)
while(TRUE)
{
loopcount++;
printf("loopcount==%d\n",loopcount);
#if defined(WIN32)
int newsock = accept(sock, (struct sockaddr *)&their_addr,&sin_size);
HANDLE handle = CreateThread(NULL, 0, LPTHREAD_START_ROUTINE(AnswerClientThread), (LPVOID)newsock, 0, NULL);
CloseHandle(handle);
#elif defined(__linux__)
int newsock = accept(sock, (struct sockaddr *)&their_addr,(socklen_t*)&sin_size);
pthread_t ntid;
//void* ntidstatus;
int err;
if((err = pthread_create(&ntid, NULL, AnswerClientThread, (void*)newsock)) != 0)
{
printf("AnswerClientThread线程创建失败!\n");
}
else
{
printf("AnswerClientThread线程被创建\n");
}
if(ntid !=0)
{
pthread_join(ntid,NULL);
printf("AnswerClientThread线程已经结束\n");
}
else
{
printf("AnswerClientThread线程未结束\n");
}
pthread_detach(ntid);
#endif
}
OCI_Cleanup();
return 0;
}
调用的函数如下
void* AnswerClientThread(void* pParam)
{
int psock = *(int*)&pParam;
int nrecvlen = 0;
char* recvbuf = new char[6400];
char* recvbufpt = recvbuf;
//printf("****** sum= %d ,%d******* \n",dw_k_run,dw_x_run);
while(TRUE)
{
recvbuf = recvbufpt;
memset(recvbuf, 0, 6400);
nrecvlen = ::recv(psock, recvbuf, 6400, 0);
if(nrecvlen == SOCKET_ERROR || nrecvlen > 6400)
{
delete [] recvbuf;
ReleasePortInManage(psock);
close(psock);
return ((void*)1);
}
int ncmd = UNKNOWN_CMD;
bool bcmd = false;
int ndatalen = 0;
while(bcmd = get_cmd(recvbuf, nrecvlen, ncmd, ndatalen))
{
printf("ncmd==%d\n",ncmd);
switch(ncmd)
{
case REGIST_CMD: // 注册命令
{
RegistDevInfo(recvbuf, nrecvlen, psock);
break;
}
case KEEPALIVE_CMD: // 心跳命令
{
KeepAlive(recvbuf, nrecvlen, psock);
break;
}
case XML_CMD: // xml
{
xml_deco(recvbuf, nrecvlen, psock);
break;
}
default: // 未知命令
{
break;
}
}
if(ncmd == REGIST_CMD || ncmd == KEEPALIVE_CMD || ncmd==XML_CMD) // 和设备的心跳维持短连接
goto end;
nrecvlen = nrecvlen-ndatalen+2;
recvbuf = recvbuf+ndatalen-2;
}
//usleep(10);
}
end:
{
// 除非客户端告知要关闭链接,否则服务器是不会主动关闭链接的
delete [] recvbufpt;
ReleasePortInManage(psock);
close(psock);
pthread_exit(NULL);
}
return ((void*)0); |
|