?? 系統一開始運行很正常,但是當接收到第299個數據包時,就發生異常,查看程序日志,得知原來自接收到299個數據包后,就不再解析接收到的數據。我本以為是網絡的問題,于是,重啟下程序,結果異常發生在了同樣的位置。這時,我猜想可能是代碼的問題,找到相關代碼,如下:
|
從代碼看不出什么異常,由于解析數據是調用pthread_create函數創建一個默認屬性的線程進行處理,如果沒有解析,那么,應該是pthread_create函數沒有創建成功。而pthread_create函數創建失敗最可能的原因應該就是系統資源不足,根據經驗,線程的默認堆棧大小是1MB,就是說,系統每創建一個線程就要至少提供1MB的內存,那么,創建線程失敗,極有可能就是內存不夠用了。從代碼中看不出有內存泄露的現象,有malloc的地方就會有free對應。而仍然出現問題,那么,唯一的解釋就是pthread_create會導致內存泄露! pthread_create創建的線程結束后,系統并未回收其資源,從而導致了泄露。
??? 然后從網上查了相關資料如下:
??? ?線程的分離狀態決定一個線程以什么樣的方式來終止自己。線程的默認屬性是非分離狀態,這種情況下,原有的線程等待創建的線程結束。只有當pthread_join()函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源。而分離線程不是這樣子的,它沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。程序員應該根據自己的需要,選擇適當的分離狀態。
???? 從上面的描述中可以得知如果調用pthread_create函數創建一個默認非分離狀態的線程,如果不用pthread_join()函數,線程結束時并不算終止,所以仍然會占用系統資源。這里有如下幾種方法解決這個問題:
1.使用pthread_join()函數回收相關內存區域。
|
2.可以調用 pthread_detach() 函數分離線程。
|
當然,也可以在 thread function 中調用。
|
3.使用線程屬性。
|
根據實際需要,任選其一即可。?
ps:最后,我寫了個測試程序,然后用valgrind檢查了一下。
測試程序:
|
[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)
確實有內存泄露。
修改測試程序:
|
[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)
問題解決。