免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6889 | 回复: 12
打印 上一主题 下一主题

linux 多线程溢出问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-15 16:48 |只看该作者 |倒序浏览
本帖最后由 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);

DeviceRegistServer.rar

10.49 KB, 下载次数: 36

论坛徽章:
0
2 [报告]
发表于 2012-05-15 17:01 |只看该作者
本帖最后由 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

                }
        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);

论坛徽章:
0
3 [报告]
发表于 2012-05-15 17:08 |只看该作者
附件是程序运行一段时间的。。内存增加8K

以后这个地址段的内存一直增加。。到无限大。

增加的内存8K.JPG (231.73 KB, 下载次数: 46)

增加的内存8K.JPG

论坛徽章:
0
4 [报告]
发表于 2012-05-16 09:45 |只看该作者
                        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);

这里面有内存溢出

有人知道怎么处理吗?

论坛徽章:
0
5 [报告]
发表于 2012-05-16 12:44 |只看该作者
问题在这几行


                delete [] recvbufpt;
                //delete [] recvbuf;
                printf("recvbufpt===%s\n",recvbufpt);
                printf("recvbuf===%s\n",recvbuf);               
                print_port();
                ReleasePortInManage(psock);


内存.jpg (6.45 KB, 下载次数: 40)

内存.jpg

论坛徽章:
0
6 [报告]
发表于 2012-05-16 14:11 |只看该作者
线程如果退出的话 收回没?

论坛徽章:
0
7 [报告]
发表于 2012-05-16 14:32 |只看该作者
回收了。
但感觉没有回收干净

                                                pthread_t loghandle1;
                                                void* logstatus;
                                                int err;
                                                if((err = pthread_create(&loghandle1, NULL, InsertLog1, lg)) != 0)
                                                        {
                                                                printf("RegistDevInfoLog线程创建失败!\n");
                                                        }
                                                else
                                                        {
                                                                printf("RegistDevInfoLog线程被创建\n");
                                                        }
                                                                printf("InsertLog1 err===%d\n",err);
                                                if(loghandle1 !=0)
                                                        {                                       
                                                                pthread_join(loghandle1,NULL);               
                                                                printf("RegistDevInfoLog线程已经结束\n");
                                                        }
                                                else
                                                        {
                                                                printf("RegistDevInfoLog线程未结束\n");               
                                                        }


                                                        pthread_detach(loghandle1);

论坛徽章:
0
8 [报告]
发表于 2012-05-17 16:34 |只看该作者
找出问题的原因了。是多线程引起的。


论坛徽章:
6
申猴
日期:2013-10-08 17:32:32金牛座
日期:2013-10-18 19:45:53天秤座
日期:2013-10-18 20:17:34处女座
日期:2014-02-11 10:10:29丑牛
日期:2014-02-15 10:44:15巳蛇
日期:2014-02-18 22:05:54
9 [报告]
发表于 2012-05-21 10:43 |只看该作者
我想知道问题原因在哪,谢谢

论坛徽章:
0
10 [报告]
发表于 2012-05-23 11:12 |只看该作者
==27312== Memcheck, a memory error detector.
==27312== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==27312== Using LibVEX rev 1658, a library for dynamic binary translation.
==27312== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==27312== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==27312== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==27312== For more details, rerun with: -v
==27312==
==27312== My PID = 27312, parent PID = 1876.  Prog and args are:
==27312==    ./DeviceRegistServer
==27312==
==27312== Thread 2:
==27312== Conditional jump or move depends on uninitialised value(s)
==27312==    at 0x4006247: strlen (mc_replace_strmem.c:246)
==27312==    by 0x1C9BCD: vfprintf (in /lib/libc-2.5.so)
==27312==    by 0x1CFE42: printf (in /lib/libc-2.5.so)
==27312==    by 0x8049AB0: AnswerClientThread(void*) (DeviceRegistServer.cpp:1164)
==27312==    by 0x30449A: start_thread (in /lib/libpthread-2.5.so)
==27312==    by 0x25B42D: clone (in /lib/libc-2.5.so)
==27312==
==27312== ERROR SUMMARY: 999 errors from 1 contexts (suppressed: 27 from 1)
==27312== malloc/free: in use at exit: 0 bytes in 0 blocks.
==27312== malloc/free: 1,000 allocs, 1,000 frees, 6,393,744 bytes allocated.
==27312== For counts of detected errors, rerun with: -v
==27312== All heap blocks were freed -- no leaks are possible.



这个是我抓的多线程冲突的问题。

我用单线程,就搞定了。

我现在也在找问题。

线程内存没有释放干净。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP