内存在C中终止线程时泄漏处理

时间:2013-04-29 07:06:17

标签: c multithreading memory pthreads

我在这里写一个C pgm,它创建一个线程并处理它。为了避免线程的内存泄漏,我正在使用pthread_cleanup_push和pthread_cleanup_pop函数,并在线程函数上最后调用pthread_exit。在运行程序时,我得到以下错误。

我相信有一些内存分配/免费问题。请帮帮我,如何在没有内存泄漏的情况下安全地终止线程。以下是我的计划: -

struct str_thrd_data
{
        SQLHANDLE hstmt;
        int rc;
        bool thrd_completed_flag;
};

void * str_in_thread_call(void *in_str_arg)
{
        int thrd_rc;
        struct str_thrd_data *str_arg;
        str_arg = in_str_arg;

        pthread_cleanup_push(free, str_arg);
        thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        if (thrd_rc != 0)
               handle_error_en(thrd_rc, "pthread_setcancelstate");

        thrd_rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        if (thrd_rc != 0)
               handle_error_en(thrd_rc, "pthread_setcancelstate");

        printf("\n*********************Normal Thread termination withing timelimit %d\n",str_arg->rc);
        str_arg->thrd_completed_flag = true;
        sleep(1);
        pthread_cleanup_pop(1);
        pthread_exit(1);
}

int main()
{
        printf("\nPJH: New THread created.\n");
        pthread_attr_t tattr;
        pthread_t th;
        size_t mysize = 1;

        struct str_thrd_data atd;

        atd.hstmt = hstmt;
        atd.rc= rc;
        atd.thrd_completed_flag = false;

        thrd_rc = pthread_attr_init(&tattr);
        thrd_rc = pthread_attr_setstacksize(&tattr, mysize);
        thrd_rc = pthread_create(&th, &tattr, &str_in_thread_call, &atd);
        if (thrd_rc != 0)
               handle_error_en(thrd_rc, "pthread_create");

        while(timeout !=0)
        {
                printf("%d Value of rc=%d\n",timeout, atd.rc);
                if(atd.rc != 999) break;
                timeout--;
                usleep(10000);
        }
        rc = atd.rc;
}

以下是我在运行程序时收到的错误消息: -

*** glibc detected *** ./myprocessname: free(): invalid pointer: 0xbc8d9f34 ***  
======= Backtrace: =========  
/lib/libc.so.6[0x5e0c65]  
/lib/libc.so.6(cfree+0x59)[0x5e4c59]  
./dcs[0x80a828a]  
/lib/libpthread.so.0[0x7c4912]  
/lib/libc.so.6(clone+0x5e)[0x64c60e]  
======= Memory map: ========  
00558000-00573000 r-xp 00000000 fd:00 393227                             /lib/ld-2.5.so  
00573000-00574000 r--p 0001a000 fd:00 393227                             /lib/ld-2.5.so  
00574000-00575000 rw-p 0001b000 fd:00 393227                             /lib/ld-2.5.so  
00577000-006ce000 r-xp 00000000 fd:00 393228                             /lib/libc-2.5.so  
006ce000-006d0000 r--p 00156000 fd:00 393228                             /lib/libc-2.5.so  
006d0000-006d1000 rw-p 00158000 fd:00 393228                             /lib/libc-2.5.so  
006d1000-006d4000 rw-p 006d1000 00:00 0  
006d6000-006fd000 r-xp 00000000 fd:00 393234                             /lib/libm-2.5.so  
006fd000-006fe000 r--p 00026000 fd:00 393234                             /lib/libm-2.5.so  
006fe000-006ff000 rw-p 00027000 fd:00 393234                             /lib/libm-2.5.so  
007a1000-007a8000 r-xp 00000000 fd:00 393417                             /lib/librt-2.5.so  
007a8000-007a9000 r--p 00007000 fd:00 393417                             /lib/librt-2.5.so  
007a9000-007aa000 rw-p 00008000 fd:00 393417                             /lib/librt-2.5.so  
007bf000-007d5000 r-xp 00000000 fd:00 393230                             /lib/libpthread-2.5.so  
007d5000-007d6000 r--p 00015000 fd:00 393230                             /lib/libpthread-2.5.so  
007d6000-007d7000 rw-p 00016000 fd:00 393230                             /lib/libpthread-2.5.so  
007d7000-007d9000 rw-p 007d7000 00:00 0  
007db000-007e6000 r-xp 00000000 fd:00 393252                             /lib/libgcc_s-4.1.20080825.so.1  
007e6000-007e7000 rw-p 0000a000 fd:00 393252                             /lib/libgcc_s-4.1.2-20080825.so.1  
007e9000-007ec000 r-xp 00000000 fd:00 393237                             /lib/libdl-2.5.so  
007ec000-007ed000 r--p 00002000 fd:00 393237                             /lib/libdl-2.5.so    
007ed000-007ee000 rw-p 00003000 fd:00 393237                             /lib/libdl-2.5.so  
00acd000-00adf000 r-xp 00000000 fd:00 393296                             /lib/libz.so.1.2.3  
00adf000-00ae0000 rw-p 00011000 fd:00 393296                             /lib/libz.so.1.2.3  
08048000-0810c000 r-xp 00000000 fd:01 1517776                            /home/myprocessname  
0810c000-08185000 rw-p 000c3000 fd:01 1517776                            /home/myprocessname  
08185000-08215000 rw-p 08185000 00:00 0  
0857b000-08aee000 rw-p 0857b000 00:00 0                                  [heap]  
1ffea000-1ffeb000 ---p 1ffea000 00:00 0  
1ffeb000-3f3eb000 rwxp 1ffeb000 00:00 0  
3f3eb000-3f42c000 rw-p 3f3eb000 00:00 0  
3f42c000-3f44c000 rw-s 00000000 00:09 1570996267                         /SYSV00000000 (deleted)  
3f44c000-3f48c000 rw-p 3f44c000 00:00 0  
3f48c000-3f4ac000 rw-s 00000000 00:09 1570963498                         /SYSV00000000 (deleted)  
3f4ac000-3f4cc000 rw-s 00000000 00:09 1570930729                         /SYSV00000000 (deleted)  
3f4cc000-3f58c000 rw-p 3f4cc000 00:00 0  
3f58c000-3f5ac000 rw-s 00000000 00:09 1570897960                         /SYSV00000000 (deleted)  
3f5ac000-3f62c000 rw-p 3f5ac000 00:00 0  
3f62c000-3f64c000 rw-s 00000000 00:09 1570865191                         /SYSV00000000 (deleted)  
3f64c000-3f6cc000 rw-p 3f64c000 00:00 0  
3f6cc000-3f6ec000 rw-s 00000000 00:09 1570832422                         /SYSV00000000 (deleted)  
3f6ec000-3f70c000 rw-s 00000000 00:09 1570799653                         /SYSV00000000 (deleted)  
3f70c000-3f72c000 rw-s 00000000 00:09 1570766884                         /SYSV00000000 (deleted)  
3f72c000-3f8ec000 rw-p 3f72c000 00:00 0  
3f8ec000-3f8ed000 ---p 3f8ec000 00:00 0  
3f8ed000-5eced000 rwxp 3f8ed000 00:00 0  
5eced000-5ecee000 ---p 5eced000 00:00 0  
5ecee000-7e0ee000 rwxp 5ecee000 00:00 0Aborted (core dumped)  

2 个答案:

答案 0 :(得分:2)

您正在尝试释放main功能的堆栈内存。这当然行不通。

在您使用pthread_create的{​​{1}}调用中,这将返回指向&atd函数堆栈上atd结构的指针。这个记忆不能也不应该被你释放。

答案 1 :(得分:1)

上述代码的另一个问题是thrd_rc = pthread_attr_setstacksize(&tattr, mysize);mysize应该是系统页面大小的倍数,否则函数将失败。