日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pthread_create会导致内存泄露

發布時間:2023/11/30 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pthread_create会导致内存泄露 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這幾天一直在調試一個系統,系統的功能就是定時發送數據、接收數據然后解析收到的數據,轉換成一定的格式存入數據庫中。我為了并發操作,所以每接收到一個數據包,就調用pthread_create函數創建一個默認屬性的線程進行處理。

?? 系統一開始運行很正常,但是當接收到第299個數據包時,就發生異常,查看程序日志,得知原來自接收到299個數據包后,就不再解析接收到的數據。我本以為是網絡的問題,于是,重啟下程序,結果異常發生在了同樣的位置。這時,我猜想可能是代碼的問題,找到相關代碼,如下:


while?(1)?
{
????len?=?recvfrom(sock,?buf,?MAXPACKETSIZE,?

??????????????????? 0,(struct?sockaddr?*)&c_addr,?&addr_len);
????.......
????targ?=?(struct?threadarg?*)malloc(sizeof(struct?threadarg));
????memset(targ,?0,?sizeof(struct?threadarg));
????????
????targ->len?=?len;
????targ->ip?=?(int)c_addr.sin_addr.s_addr;
????memcpy(targ->buffer,?buf,?len);
????printf("received\n");
????????

????//注:targ在線程中會被free掉。

????pthread_create(&tid,?NULL,?insertToList,?(void?*)targ);
}


從代碼看不出什么異常,由于解析數據是調用pthread_create函數創建一個默認屬性的線程進行處理,如果沒有解析,那么,應該是pthread_create函數沒有創建成功。而pthread_create函數創建失敗最可能的原因應該就是系統資源不足,根據經驗,線程的默認堆棧大小是1MB,就是說,系統每創建一個線程就要至少提供1MB的內存,那么,創建線程失敗,極有可能就是內存不夠用了。從代碼中看不出有內存泄露的現象,有malloc的地方就會有free對應。而仍然出現問題,那么,唯一的解釋就是pthread_create會導致內存泄露! pthread_create創建的線程結束后,系統并未回收其資源,從而導致了泄露。

??? 然后從網上查了相關資料如下:


??? ?線程的分離狀態決定一個線程以什么樣的方式來終止自己。線程的默認屬性是非分離狀態,這種情況下,原有的線程等待創建的線程結束。只有當pthread_join()函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源。而分離線程不是這樣子的,它沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。程序員應該根據自己的需要,選擇適當的分離狀態。

???? 從上面的描述中可以得知如果調用pthread_create函數創建一個默認非分離狀態的線程,如果不用pthread_join()函數,線程結束時并不算終止,所以仍然會占用系統資源。這里有如下幾種方法解決這個問題:
1.使用pthread_join()函數回收相關內存區域。

pthread_t?tid;
void*?state;

pthread_create(&tid,?NULL,?test,?NULL);
pthread_join(tid,?&state);


2.可以調用 pthread_detach() 函數分離線程。

pthread_t?tid;
pthread_create(&tid,?NULL,?test,?NULL);
pthread_detach(tid);


當然,也可以在 thread function 中調用。


void*?test(void*?arg)
{
????.....
????pthread_detach(pthread_self());
????return?NULL;
}


3.使用線程屬性。


pthread_attr_t?attr;
pthread_t?tid;

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,?PTHREAD_CREATE_DETACHED);

pthread_create(&tid,?&attr,?test,?NULL);

sleep(3);//等待線程結束

pthread_attr_destroy(&attr);


根據實際需要,任選其一即可。?


ps:最后,我寫了個測試程序,然后用valgrind檢查了一下。
測試程序:

#include?<pthread.h>
#include?<stdio.h>

void*?test()
{
????printf("ok\n");
????return;
}
int?main(int?argc,?char**?argv)
{
????????pthread_t?tid;
????????pthread_create(&tid,?NULL,?test,?NULL);
????//pthread_join(tid, NULL);

????return?1;
}

編譯鏈接:
[root@localhost ~]# gcc -g b.c -o b -lpthread
然后,用valgrind進行內存檢查

[root@localhost ~]# valgrind --tool=memcheck --leak-check=full ./b
==20980== Memcheck, a memory error detector
==20980== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==20980== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==20980== Command: ./b
==20980==?
ok
==20980==?
==20980== HEAP SUMMARY:
==20980==???? in use at exit: 272 bytes in 1 blocks
==20980==?? total heap usage: 1 allocs, 0 frees, 272 bytes allocated
==20980==?
==20980== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==20980==??? at 0x4C1F1A0: calloc (vg_replace_malloc.c:418)
==20980==??? by 0x4010422: _dl_allocate_tls (in /lib64/ld-2.7.so)
==20980==???? by 0x4E2AB52: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.7.so)
==20980==??? by 0x40059E: main (b.c:13)
==20980==?
==20980== LEAK SUMMARY:
==20980==??? definitely lost: 0 bytes in 0 blocks
==20980==??? indirectly lost: 0 bytes in 0 blocks
==20980==????? ?possibly lost: 272 bytes in 1 blocks
==20980==??? still reachable: 0 bytes in 0 blocks
==20980==???????? suppressed: 0 bytes in 0 blocks
==20980==?
==20980== For counts of detected and suppressed errors, rerun with: -v
==20980== ERROR SUMMARY:? 1 errors from 1 contexts ?(suppressed: 4 from 4)

確實有內存泄露。
修改測試程序:


#include?<pthread.h>
#include?<stdio.h>

void*?test()
{
????printf("ok\n");
????return;
}
int?main(int?argc,?char**?argv)
{
????????pthread_t?tid;
????????pthread_create(&tid,?NULL,?test,?NULL);
????pthread_join(tid,?NULL);
????return?1;
}

編譯鏈接:
[root@localhost ~]# gcc -g b.c -o b -lpthread
然后,用valgrind進行內存檢查

[root@localhost ~]# valgrind --tool=memcheck --leak-check=full ./b
==21013== Memcheck, a memory error detector
==21013== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==21013== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==21013== Command: ./b
==21013==?
ok
==21013==?
==21013== HEAP SUMMARY:
==21013==???? in use at exit: 0 bytes in 0 blocks
==21013==??? total heap usage: 1 allocs, 1 frees, 272 bytes allocated
==21013==?
==21013== All heap blocks were freed -- no leaks are possible
==21013==?
==21013== For counts of detected and suppressed errors, rerun with: -v
==21013== ERROR SUMMARY:? 0 errors from 0 contexts ?(suppressed: 4 from 4)

問題解決。

總結

以上是生活随笔為你收集整理的pthread_create会导致内存泄露的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。