c語言線程池
Ⅰ 對於c語言來說 線程池的作用是什麼
為什麼達不到?線程和什麼語言無關,這是操作系統的概念,或者說是第三方庫提供的概念。
Ⅱ linux下 c 語言線程池怎麼調用
1 使用線程池的原因
通常使用多線程都是在需要的時候創建一個新的線程,然後執行任務,完成後退出。一般情況下是完全夠滿足我們的程序的。
但是當我們需要創建大量的線程,並且執行一個簡單的任務之後銷毀,比如:在web,email,db裡面的一些應用,如彩鈴,或者網路通信編程,或者雲計算裡面後台鏡像處理的時候,我們的應用在任何時候都要准備面對數目巨大的連接請求,同時,這些請求執行的任務卻又比較簡單,佔用的時間很少,這樣我們可能就會處於不停的創建線程並銷毀線程的狀態。雖說比起進程的創建,線程的創建時間已經大大縮短,但是如果需要頻繁的創建線程,並且每個線程所佔用的處理時間又非常簡短,則線程創建和銷毀帶給處理器的額外負擔也是很可觀的。
線程池的作用正是在這種情況下有效的降低頻繁創建銷毀線程所帶來的額外開銷。一般來說,線程池都是採用預創建的技術,在應用啟動之初便預先創建一定數目的線程。應用在運行的過程中,需要時可以從這些線程所組成的線程池裡申請分配一個空閑的線程,來執行一定的任務,任務完成後,並不是將線程銷毀,而是將它返還給線程池,由線程池自行管理。如果線程池中預先分配的線程已經全部分配完畢,但此時又有新的任務請求,則線程池會動態的創建新的線程去適應這個請求。當然,有可能,某些時段應用並不需要執行很多的任務,導致了線程池中的線程大多處於空閑的狀態,為了節省系統資源,線程池就需要動態的銷毀其中的一部分空閑線程。因此,線程池都需要一個管理者,按照一定的要求去動態的維護其中線程的數目。
當然,如果線程創建和銷毀時間相比任務執行時間可以忽略不計,則沒有必要使用線程池了。
Ⅲ 幫忙看看windows下C語言編寫線程池
如果創建只用一個線程,那隻能一個個取了執行。
想並行,只能用一個線程來取地址,然後發送到各個多個已有線程,再由這些線程來完成創建工作。
至於線程池,參考網上的,這個沒什麼特別的。
Ⅳ C語言如何使用線程池中的某個線程
問別人問題,還這么牛叉,真心佩服
不要給線程派任務,讓線程空閑的時候,自己去領任務
Ⅳ C語言:編寫函數fun返回二維數組周邊元素之和,咋寫
入門到放棄?
「C/C++真的太難學了,我准備放棄了!」
很多初學者在學完C和C++的基本語法後,就停滯不前了,最終走向「從入門到放棄」。其實,我們初學者最需要的不是HelloWorld,也不是語法知識的堆砌,需要的只是實戰項目的磨礪。
一個項目一座城
一個項目,一座城。寫完一個項目,攻克一座城池。
以下十三個循序漸進的項目,讓你從小白,快速晉升為大牛。
奇牛項目1《黑客攻擊系統》-第一城
從完全零基礎開始,手把手開發這款黑客攻擊系統。
通過用戶端的輸入, 向伺服器端木馬發送攻擊命令,實現多種方式的攻擊效果。
通過這個項目,可以掌握C/C++基礎(數據類型,變數的使用,各種運算,控制語句,命名空間,輸入輸出,函數調用,庫文件的使用等),直接使用圖形庫來實現窗口用戶界面,直接使用庫文件來實現攻擊效果。
奇牛項目2 《人工智慧地形導航系統》-第二城
具備C/C++基礎後,進一步學習二維數組、多維數組在工程項目中的應用。
根據地圖的海拔數據,來識別地形上的各個峰點(最高點)和谷點(最低點),以確定地形中峰點的數目和位置,為探測器提供導航數據。
通過這個項目,可以深刻掌握二維數組、多維數組的本質,以及在工程項目中的應用方法。
奇牛項目3《人工智慧雙色球預測系統》-第三城
根據筆者Rock的閑暇之作改寫,體會以小博大的樂趣。
通過自動分析博彩官網的海量數據,根據自定義的統計預測規則,來捕捉下期開獎的最大概率。
通過這個項目,掌握指針的使用,以及指針在工程項目中的應用。
奇牛項目4《地震監測系統》-第四城
地震檢波器每隔固定的時間間隔,采樣一次預測地震的能量數據,並保存到文件中。地震監測系統從這個文件中讀取相應的能量數據,測試在給定的時間點上,一個短時間窗口內的取樣值與一個長時間窗口內取樣值的商,如果這個比例高於給定的閾值,那麼在這個事件點上極有可能發生地震。
通過這個項目,掌握C/C++文件的讀寫、以及動態內存管理的使用,以及它們在工程項目中的應用。
奇牛項目5《智能婚戀交友系統》-第五城
程序員的相親活動,低調且奢華。這個項目直接致敬某XX佳緣婚戀交友平台,畢竟Rock也曾經是該平台的注冊會員,並在其中活躍良久。
這個項目實現了該平台的核心功能-高匹配度自動交友。
通過這個項目,掌握C++的面向對象思想、繼承和派生、多態、友元、運算符重載等核心機制,以及它們在工程中的應用。
奇牛項目6《廣州軍區微波通信系統》-第六城
這個項目是根據筆者Rock負責研發的廣州軍區南海無線微波通信系統改寫的, 已去除敏感數據。
這個項目是在菲律賓、越南肆意騷擾我國南海島嶼的背景下研發的。通過這個項目,掌握C++核心機制-多態的使用,以及在軍事工程項目中的應用。
奇牛項目7《模板庫高級編程-萬能擇優器》-第七城
在掌握了C、C++的核心特性之後,能否掌握C++標准模板庫STL, 是區分一名合格C++程序員的重要標志。
這個項目通過構建一個通用的擇優器,來掌握C++泛型編程的使用,以及在自定義模塊開發中的應用。
奇牛項目8《游戲伺服器端資料庫》-第八城
在征服了C/C++語言的核心特性之後,很多人會感到新的迷茫:C/C++語言到底能做什麼?海量用戶數據怎麼處理?
這個項目從零開始構建大型游戲資料庫,以掌握資料庫開發的方法,以及在產品級項目中的應用。
奇牛項目9 《企業QQ》-第九城
很多C/C++初學者,認為C和C++雖然很強大,但是對於用戶界面開發,就不是很方便了。
其實對於用戶界面的開發,C和C++,尤其是C++,是非常強悍的。各種絢麗的用戶界面,C++都能游刃有餘地呈現。
這個項目能夠深度掌握基於C++的用戶界面開發,以及網路編程,實現產品級的應用效果。
奇牛項目10 《跨平台Word》-第十城
IT外包開發時,用戶的需求總是千變萬化,界面和功能都需要做特殊的定製,這個項目讓我們掌握開發特定UI和特定功能的應用軟體,為以後獨立承接IT外包打下足夠的基礎。
奇牛項目11《 游戲外*修改器》-第十一城
外*、逆向、破解無疑是每一位程序員為之嚮往的「禁地」,這個項目融合逆向、匯編、DLL注入、內存篡改等黑技術,開發客戶端游戲的外掛,實現對游戲數據的截取、修改。
通過這個項目,可以深刻掌握指針、逆向、DLL注入等技術的使用,以及Windows客戶端應用的開發。
奇牛項目12 《人工智慧中國象棋人機對弈》-第十二城
完勝李世石和柯潔的阿爾法狗,其底層框架就是使用C++實現的。
除了圍棋,C++更是在象棋領域完勝人類。這個項目,就是使用C++打造的人工智慧象棋。
通過這個項目,可以輕松掌握各種復雜數據結構,把個人編程能力提升到極致。
奇牛項目13 《電信級大型互聯網項目-共享順風車系統》-第十三城
掌握C、C++客戶端開發之後,高性能伺服器開發,成為判別C++高級程序員的重要標志。這個項目將實現電信級的大型互聯網伺服器。
通過奇牛編程的項目實戰,可以掌握百萬級高並發伺服器的核心技術(線程池、epool架構、協議開發等)
敲代碼的夜,清脆的鍵擊,孤獨而堅定。
彈指間,攻城略地,早已硝煙彌漫。
十三座城池,待你來征服。
經過以上13個項目的修煉,你已經從小白蛻變為能夠駕馭大型項目開發的大牛了。
Ⅵ windows C語言實現線程池
戶提供連接,也就是50個線程。多餘的其它客戶連接會被阻塞直到有空餘的連接出現。其實就是所謂的「線程池」的概念,你可以搜搜這方面的內容,很多很多的。
Ⅶ C語言如何使用線程池中的某個線程
問別人問題,還這么牛叉,真心佩服
不要給線程派任務,讓線程空閑的時候,自己去領任務
Ⅷ c語言線程池關於空閑線程隊列的疑問
沒錯,沒有這些隊列照樣可以做線程池,只是有了這些隊列可以控制一下每個工作線程的負載
Ⅸ c語言epool怎麼和線程池一起使用
一, 背景
先說下我要實現的功能,server端一直在linux平台下面跑,當客戶端有請求過來的時候server端接受到請求,拿到客戶端的數據,根據拿到的數據做出相應的處理,得到處理的結果直接把結果數據發送給客戶端。這樣一個連接的請求結束,我的不是長連接的情況,不會一直保持客戶端的連接。來一個處理一個處理完了就結束了。
二,源碼下載(包括客戶端測試代碼)
我把邏輯處理部分簡單化了,如果這份代碼對你們有用的話,可以自己實現邏輯處理部分。
代碼是要傳入參數的,埠
代碼我已經在Linux下面編譯過了,也測試號了,因為代碼中用到了資料庫,如果你沒有編譯過可能要在Linux下裝Mysql資料庫。
源碼下載地址
三,代碼的簡單介紹
socket接受線程:C語言為了高並發所以選擇了epoll。當程序啟動的時候(g_net_update.c文件中main函數,會啟動一個thread見函數create_accept_task)這個thread就處理一件事情,只管接收客戶端的連接,當有連接進來的時候 通過epoll_ctl函數,把socket fd 加入到epoll裡面去,epoll設置監聽事件EPOLLIN | EPOLLET; 主要是監聽的是加入到epoll中的socket是否可讀(因為我的需求是客戶端連上了server就會馬上向server發送一份數據的)。其它的部分在主線程中處理。
主線程:是一個無線循環,epoll_wait 函數相當於把客戶端的連接從epoll中拿出來(因為我們監聽的是EPOLLIN | EPOLLET)說明這個時候客戶端有數據發送過來)。再通過recv_buffer_from_fd 函數把客戶端發送過來的數據讀出來。然後其他的一切就拋給線程池去處理。
線程池:(代碼中我會在池裡面創建15個線程) 雙向鏈表。加入線程就是在鏈表後面加一個鏈表項,鏈表的前面會一個一個被拿出來處理。主要是malloc 函數free函數,sem_wait函數sem_post的處理(sem_wait 會阻塞當值大於0是會減一,sem_post是值加一)。typedef void* (FUNC)(void arg, int index);是我們自定義的線程的邏輯處理部分,arg是參數,index是第幾個線程處理(我們隱形的給每個線程都標了號),例如代碼中的respons_stb_info,更加具體可以看看代碼裡面是怎麼實現的。聰明的你也可以改掉這塊的內容改成動態線程池,當某個時刻的處理比較多的時候能夠動態的增加線程,而不像我代碼裡面的是固定的。
資料庫連接池:按照我的需求在處理客戶端請求數據的時候是要訪問資料庫的。就是一下子創建出一堆的數據連接。要訪問資料庫的時候先去資料庫連接池中找出空閑的連接,具體可以看下代碼。使用的時候可以參考下database_process.c文件(代碼中資料庫連接池和線程池中的個數是一樣的)。這里我想說下get_db_connect_from_pool這個函數,我用了隨機數,我是為了不想每次都從0開始去判斷哪個連接沒有用到。為了資料庫連接池中的每個鏈接都能等概率的使用到,具體的還是可以看下代碼的實現。
log文件,代碼中是可以自動保存log信息到文件中去的,具體可以看下代碼。
四,碰到的一些問題和解決辦法
最初的時候server程序跑起來佔掉了linux 90%多的使用率,因為是我們在create_accept_task 中socket沒有設置成阻塞的。
server經常碰到一些莫名其妙的死機,沒辦法用了core mp 去抓死機的堆棧信息看在哪個函數死機的。
在處理資料庫的時候有的數據會自動的斷掉(說是說8個小時) 後來採用的辦法是每次都先mysql_ping一次讓他重新連接上。
就說幾點吧,其實還有好多其他的就不說了。
五,在Linux下面用到的幾個命令
./server程序名 & //加&後台運行。
killall server程序名 // 停掉server的運行。要在server目錄下面執行
netstat -antp|grep :埠號 // 查看埠下的socket狀態
ps -eaf | grep server程序名 // 檢查程序是否在運行,不過我一般是netstat -antp|grep :埠號 來看程序是否在運行。
好了 就到這里吧,如果你想實現java的高並發可以稍微看下 Linux java + apache mina + maven 實現高並發伺服器
頂
2
踩
Ⅹ 線程池中空閑的線程處於什麼狀態
一:阻塞狀態,線程並沒有銷毀,也沒有得到CPU時間片執行;
源碼追蹤:
for (;;) {
...
workQueue.take();
...
}
public E take()...{
...
while (count.get() == 0) { / /這里就是任務隊列中的消息數量
notEmpty.await();
}
...
}
public final void await()...{
...
LockSupport.park(this);
...
}
繼續往下:
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
U.park(false, 0L);
setBlocker(t, null);
}
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
//線程調用該方法,線程將一直阻塞直到超時,或者是中斷條件出現。
public native void park(boolean isAbsolute, long time);
上面就是java11線程池中阻塞的源碼追蹤;
二.對比object的wait()方法:
@FastNative
public final native void wait(long timeout, int nanos) throws InterruptedException;
還有Thread的sleep() 方法:
@FastNative
private static native void sleep(Object lock, long millis, int nanos)throws...;
可見,線程池中使用的阻塞方式並不是Object中的wait(),也不是Thread.sleep() ;
這3個方法最終實現都是通過c&c++實現的native方法.
三.在<<Java虛擬機(第二版)>>中,對線程狀態有以下介紹:
12.4.3狀態轉換
Java語言定義了5種線程狀態,在任意一個時間點,一個線程只能有且只有其中的一種
狀態,這5種狀態分別如下。
1)新建(New):創建後尚未啟動的線程處於這種狀態。
2)運行(Runable):Runable包括了操作系統線程狀態中的Running和Ready,也就是處於此
狀態的線程有可能正在執行,也有可能正在等待著CPU為它分配執行時間。
3)無限期等待(Waiting):處於這種狀態的線程不會被分配CPU執行時間,它們要等待被
其他線程顯式地喚醒。以下方法會讓線程陷入無限期的等待狀態:
●沒有設置Timeout參數的Object.wait()方法。
●沒有設置Timeout參數的Thread.join()方法。
●LockSupport.park()方法。
4)限期等待(Timed Waiting):處於這種狀態的線程也不會被分配CPU執行時間,不過無
須等待被其他線程顯式地喚醒,在一定時間之後它們會由系統自動喚醒。以下方法會讓線程
進入限期等待狀態:
●Thread.sleep()方法。
●設置了Timeout參數的Object.wait()方法。
●設置了Timeout參數的Thread.join()方法。
●LockSupport.parkNanos()方法。
●LockSupport.parkUntil()方法。
5)阻塞(Blocked):線程被阻塞了,「阻塞狀態」與「等待狀態」的區別是:「阻塞狀態」在等
待著獲取到一個排他鎖,這個事件將在另外一個線程放棄這個鎖的時候發生;而「等待狀
態」則是在等待一段時間,或者喚醒動作的發生。在程序等待進入同步區域的時候,線程將
進入這種狀態。
結束(Terminated):已終止線程的線程狀態,線程已經結束執行。