Thrift框架中函數棧的大小對程序的影響

寫一套程序,WebService的用了Thrift,還有一個單機版。單機版運行一直正常,Thrift版卻總Crash在一個功能類的一個成員函數上。注意,是成員函數上,而不是成員函數裏。但在GDB的調試過程中,運行無比正常,用GDB調試Core就顯示在了該函數上。

出錯原因是在運行時編譯器發現函數中對棧空間的使用它搞不定了,就是太大了,於是在進入函數前就Crash掉了。

於是縮小了該函數中對棧的空間使用,正常通過。

也嘗試了用各種方式來增加程序對棧的使用上限。

1. 用ulimit -s 查看大小,但用ulimit -s 40960等增加也並不管用。

2. 看一個帖子:http://zjf30366.blog.163.com/blog/static/4111645820117453719575/

用這樣的程序來修改線程棧大小:

   void *stackaddr;
    size_t stacksize;
    size_t guardsize;
    pthread_attr_t attr;

    if (pthread_attr_init(&attr) != 0){
        printf("init attr failed.\n");
        return -1;
    }   

    if (pthread_attr_getstacksize(&attr,&stacksize) == 0){
        printf("default stacksize:0x%x\n",stacksize);
    }   

    if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
        printf("default stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
    }   
    if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
        printf("default guardsize:%u\n",guardsize);
    }   
    stacksize = 40960;
    if (pthread_attr_setstacksize(&attr,stacksize) != 0){
        printf("set thread stack size failed,error:%s\n",strerror(errno));
        return -1;
    }   

    printf("-----------\n");
    if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
        printf("after set stacksize,stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
    }   

    if (pthread_attr_setstack(&attr,(void *)0x80000,stacksize) !=  0){
        printf("set stack error:%s\n",strerror(errno));
    }   
    if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
        printf("after set stack,guardsize:%u\n",guardsize);
    }   

    if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
        printf("after setstack,stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
    }   
    printf("-----------\n");
    if (pthread_attr_getstacksize(&attr,&stacksize) == 0){
        printf("default stacksize:0x%x\n",stacksize);
    }   

    if (pthread_attr_getstack(&attr,&stackaddr,&stacksize) == 0){
        printf("default stacksize:0x%x,stack addr:%p\n",stacksize,stackaddr);
    }   
    if (pthread_attr_getguardsize(&attr,&guardsize) == 0){
        printf("default guardsize:%u\n",guardsize);
    }   

也並不管用。


3. 用Thrift的PosixThreadFactory類中的void setStackSize(int value)函數來設置線程棧大小,該問題得以解決。

我是用的Thrift中非阻塞的方式:

   threadManager = ThreadManager::newSimpleThreadManager(100);
    shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
    int nStackSize = threadFactory->getStackSize();
    printf("1:stack size:%d\n", nStackSize); // default value is 1

    threadFactory->setStackSize(10);
    
    nStackSize = threadFactory->getStackSize();
    printf("2:stack size:%d\n", nStackSize);


    threadManager->threadFactory(threadFactory);
    threadManager->start();
       
總結:

單機版運行無誤,Thrift版運行Crash,是因爲函數中除了自身需要的,Thrift也會佔去一部分,而且不好用系統的系統的線程棧函數來修改,而用Thrift自已的接口函數來修改。

爲求保險還是應該縮小函數中對棧空間的使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章