2013-04-29 77 views
1

我在这里写一个C pgm,它创建一个线程并处理它。为了避免线程发生内存泄漏,我使用了pthread_cleanup_push和pthread_cleanup_pop函数,并且最后在线程函数中调用了pthread_exit。运行该程序时,出现以下错误。内存泄漏处理,同时终止线程C

我相信一些内存分配/免费问题在那里。请帮助我,我怎样才能安全地终止没有内存泄漏的线程。下面是我的程序: -

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) 
+0

您应该调用'pthread_join'来代替忙线等待线程退出主线程。这也释放了线程系统内部使用的一些数据。 – 2013-04-29 07:21:46

回答

2

你试图释放内存堆栈为main功能上。那当然不起作用。

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

+0

我不想释放结构atd。一旦完成,我想释放线程函数str_in_thread_call使用的所有本地内存。你能告诉我如何实现它,以及我使用过的方式“pthread_cleanup_push(free,str_arg)和pthread_cleanup_pop(1)”是否正确? – CodeCodeCode 2013-04-29 07:14:14

+0

@PalLoveCoding但'str_arg'取自线程参数,它是'&atd'。 'pthread_create'不会分配新内存,它甚至不提供您传递的数据大小。由于线程共享内存空间,您只需将实际的指针传递给'pthread_create'。 – 2013-04-29 07:19:13

+0

@PalLoveCoding检查调试器将非常容易。在'pthread_create'调用上设置一个断点,并在线程函数上设置一个断点。比较'&atd'和'in_str_arg'的值。你会看到他们确实是一样的,这意味着他们都指向相同的记忆。 – 2013-04-29 07:23:38

1

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