今天把creatthread與_beginthreadex的區別弄明白了,由此還給我提了個醒,關於現在監控程式中全域性函式在多執行緒中的使用,之前沒有這方面的意識,所以**中的很多處實現存在安全隱患(可能會導致意想不到的結果),現找到兩處:
(1)全域性變數echolabel的使用,由於收發訊息都在wor**程中執行,且wo**程與主線程間的通訊用的是sendmessage,暫時不會有問題,但有隱患;
(2)由sendmeg結構體組成的鍊錶的使用,用兩個指標分別指向鍊錶的頭尾。在主線程中insert節點,在wor**程中delete節點,問題就出現在這兩個函式中對兩個指標的操作。
creatthread 與 _beginthreadex這三個函式的區別
creatthread是win32 api函式,而_beginthreadex屬於c runtime函式,_beginthreadex內部呼叫了creatthread。
為什麼要有這樣的兩個建立執行緒的函式呢?最重要在於creatthread在一種應用場景下有乙個很大的缺陷,在使用creatthread的情況下呼叫c++ runtimelibrary的函式,而被呼叫的函式使用了全域性變數(確切的說是要求tiddata結構的全域性變數,這個結構下面有解釋),這樣的話會出現不安全的問題。
不安全指的是記憶體洩露的問題,那麼是怎麼造成的,為什麼_beginthreadex沒有這樣的問題?
要求tiddata結構的c runtime函式在被呼叫後會有下面這些動作:
c runtime函式試圖tlsgetalue獲取執行緒資料結構的位址,如果沒有獲取到,函式就會現場分配乙個 tiddata結構,並且和執行緒相關聯。如果不通_endthreadex函式來終結執行緒的話,這個結構將不會被撤銷,記憶體洩漏就會出現了。但通常情況下,我們都不推薦使用_endthreadex函式來結束執行緒,因為裡面包含了exitthread呼叫。
createthread函式不產生這樣的tiddata結構,而_beginthreadex在產生執行緒的同時,還構建了乙個堆結構(tiddata結構,通過執行緒本地存貯器與執行緒關聯起來),這個堆結構用來儲存執行緒入口函式位址和一些資料,比如說errno之類的執行緒全域性變數。我認為tiddata結構的由來是這樣的,多執行緒版本下的ctl(c runtime library)函式與單執行緒版本下的區別主要是在對使用了全域性變數的那些函式實現上,在多執行緒情況下使用全域性變數會有很多預料不到的事,所以才會有同步機制,多執行緒版本的ctl對此的應對措施就是在函式中使用tiddata結構,用來讀取和儲存全域性變數。
在《win32多執行緒程式設計》中總結了幾條準則,何時使用_beginthreadex。
1 使用malloc()和free(),或是new和delete
2 使用stdio.h或io.h裡面宣告的任何函式
3 使用浮點變數或浮點運算函式
4 呼叫任何乙個使用了靜態緩衝區的runtime函式,比如:asctime(),strtok()或rand()
注:全域性變數errno用來存放錯誤原因,效果跟win32平台下的getlasterror()一樣。
學習筆記 雜湊學習筆記
hash基本原理 hash就是乙個像函式一樣的東西,你放進去乙個值,它給你輸出來乙個值。輸出的值就是hash值。一般hash值會比原來的值更好儲存 更小 或比較。那字串hash就非常好理解了。就是把字串轉換成乙個整數的函式。而且要盡量做到使字串對應唯一的hash值。它的主要思路是選取恰當的進製,可以...
學習筆記 CentOS 學習筆記01
簡單的做個課堂筆記 虛擬機器用的是vmware,系統是centos cd etc sysconfig network scripts pwdls 顯示列表 cat ifcfg eth0 檢視檔案內容 vi ifcfg eth0 進入vi編輯器 onboot no 原始設定 x逐字刪除 d刪除整行 a...
筆記 spring cloud 學習筆記
1 spring cloud 是什麼 spring cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具 例如配置管理,服務發現,斷路器,智慧型路由,微 控制匯流排 分布式系統的協調導致了樣板模式,使用spring cloud開發人員可以快速地支援實現這些模式的服務和應用程式。他們將在任...