linux c++ 多线程(c linux 多线程)
c語言多線程詳解?
概念
線程:線程是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器(棧指針、程序計(jì)數(shù)器等),但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。
多線程:多線程是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來執(zhí)行不同的任務(wù),也就是說允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來完成各自的任務(wù)。
C語言的開始設(shè)計(jì),并未設(shè)計(jì)多線程的機(jī)制,由于隨著軟硬件的發(fā)展及需求的發(fā)展。后來C語言才開發(fā)了線程庫以支持多線程的操作、應(yīng)用。
主要基于Linux介紹C多線程。在編譯C的多線程時(shí)候,一方面必須指定Linux C語言線程庫多線程庫pthread,才可以正確編譯(例如:gcc test.c -o test -lpthread);另一方面要包含有關(guān)線程頭文件#include <pthread.h>。
linux怎么查看一個(gè)進(jìn)程的所有線程?
使用ps命令
常用參數(shù):
-a顯示所有進(jìn)程(等價(jià)于-e)(utility)
-a顯示一個(gè)終端的所有進(jìn)程,除了會(huì)話引線
-n忽略選擇。
-d顯示所有進(jìn)程,但省略所有的會(huì)話引線(utility)
-x顯示沒有控制終端的進(jìn)程,同時(shí)顯示各個(gè)命令的具體路徑。dx不可合用。(utility)
-ppid進(jìn)程使用cpu的時(shí)間
-uuidorusername選擇有效的用戶id或者是用戶名
-ggidorgroupname顯示組的所有進(jìn)程。
uusername顯示該用戶下的所有進(jìn)程,且顯示各個(gè)命令的詳細(xì)路徑。如:psuzhang;(utility)
-f全部列出,通常和其他選項(xiàng)聯(lián)用。如:ps-faorps-fxandsoon.
-l長格式(有f,wchan,c等字段)
-j作業(yè)格式
-o用戶自定義格式。
v以虛擬存儲(chǔ)器格式顯示
s以信號(hào)格式顯示
-m顯示所有的線程
-h顯示進(jìn)程的層次(和其它的命令合用,如:ps-ha)(utility)
e命令之后顯示環(huán)境(如:ps-de;ps-ae)(utility)
h不顯示第一行
ps命令常用用法:
1)psa顯示現(xiàn)行終端機(jī)下的所有程序,包括其他用戶的程序。
2)ps-a顯示所有進(jìn)程。
3)psc列出程序時(shí),顯示每個(gè)程序真正的指令名稱,而不包含路徑,參數(shù)或常駐服務(wù)的標(biāo)示。
4)ps-e此參數(shù)的效果和指定"a"參數(shù)相同。
5)pse列出程序時(shí),顯示每個(gè)程序所使用的環(huán)境變量。
6)psf用ascii字符顯示樹狀結(jié)構(gòu),表達(dá)程序間的相互關(guān)系。
7)ps-h顯示樹狀結(jié)構(gòu),表示程序間的相互關(guān)系。
8)ps-n顯示所有的程序,除了執(zhí)行ps指令終端機(jī)下的程序之外。
9)pss采用程序信號(hào)的格式顯示程序狀況。
10)pss列出程序時(shí),包括已中斷的子程序資料。
11)ps-t指定終端機(jī)編號(hào),并列出屬于該終端機(jī)的程序的狀況。
12)psu以用戶為主的格式來顯示程序狀況。
13)psx顯示所有程序,不以終端機(jī)來區(qū)分。
最常用的方法是ps-aux或ps-ef,然后再利用一個(gè)管道符號(hào)導(dǎo)向到grep去查找特定的進(jìn)程,然后再對(duì)特定的進(jìn)程進(jìn)行操作。
Linux多線程通信?
PIPE和FIFO用來實(shí)現(xiàn)進(jìn)程間相互發(fā)送非常短小的、頻率很高的消息;
這兩種方式通常適用于兩個(gè)進(jìn)程間的通信。
共享內(nèi)存用來實(shí)現(xiàn)進(jìn)程間共享的、非常龐大的、讀寫操作頻率很高的數(shù)據(jù)(配合信號(hào)量使用);
這種方式通常適用于多進(jìn)程間通信。
其他考慮用socket。這里的“其他情況”,其實(shí)是今天主要會(huì)碰到的情況:
分布式開發(fā)。
在多進(jìn)程、多線程、多模塊所構(gòu)成的今天最常見的分布式系統(tǒng)開發(fā)中,
socket是第一選擇
。
消息隊(duì)列,現(xiàn)在建議不要使用了 ---- 因?yàn)檎也坏绞褂盟鼈兊睦碛伞?/p>
在實(shí)際中,我個(gè)人感覺,PIPE和FIFO可以偶爾使用下,共享內(nèi)存都用的不多了。在效率上說,socket有包裝數(shù)據(jù)和解包數(shù)據(jù)的過程,所以理論上來說socket是沒有PIPE/FIFO快,不過現(xiàn)在計(jì)算機(jī)上真心不計(jì)較這么一點(diǎn)點(diǎn)速度損失的。你費(fèi)勁糾結(jié)半天,不如我把socket設(shè)計(jì)好了,多插一塊CPU來得更劃算。
另外,進(jìn)程間通信的數(shù)據(jù)一般來說我們都會(huì)存入數(shù)據(jù)庫的,這樣萬一某個(gè)進(jìn)程突然死掉或者整個(gè)服務(wù)器死了,也不至于丟失重要數(shù)據(jù)、便于回滾到之前的狀態(tài)。從這個(gè)角度考慮,適用共享內(nèi)存的情況也更少了,所以socket使用得更多。再多說一點(diǎn)關(guān)于共享內(nèi)存的:共享內(nèi)存的效率確實(shí)高,但它的重點(diǎn)在“共享”二字上。如果的確有好些進(jìn)程共享一大塊數(shù)據(jù)(如果把每個(gè)進(jìn)程都看做是類的對(duì)象的話,那么共享數(shù)據(jù)就是這個(gè)類的static數(shù)據(jù)成員),那么共享內(nèi)存就是一個(gè)不二的選擇了。但是在面向?qū)ο蟮慕裉欤覀兏嗟臅r(shí)候是多線程+鎖+線程間共享數(shù)據(jù)。因此共享進(jìn)程在今天使用的也越來越少了。
不過,在面對(duì)一些極度追求效率的需求時(shí),共享內(nèi)存就會(huì)成為唯一的選擇,比如高頻交易系統(tǒng)。除此以外,一般是不需要特意使用共享內(nèi)存的。另外,
PIPE和共享內(nèi)存是不能跨LAN的
(FIFO可以但FIFO只能用于兩個(gè)進(jìn)程通信)
。
如果你的分布式系統(tǒng)隨著需求的增加而越來越大所以你想把不同的模塊放在不同機(jī)器上而你之前開發(fā)的時(shí)候用了PIPE或者共享內(nèi)存,那么你將不得不對(duì)代碼進(jìn)行大幅修改......同時(shí),即使FIFO可以跨越LAN,其代碼的可讀性、易操作性和可移植性、適應(yīng)性也遠(yuǎn)沒有socket大。這也就是為什么一開始說socket是第一選擇的原因。
最后還有個(gè)信號(hào)簡單說一下。
請(qǐng)注意,是信號(hào),不是信號(hào)量。
信號(hào)量是用于同步線程間的對(duì)象的使用的(建議題主看我的答案,自認(rèn)為比較通俗易懂:
semaphore和mutex的區(qū)別? - Linux - 知乎
)。
信號(hào)也是進(jìn)程間通信的一種方式。比如在Linux系統(tǒng)下,一個(gè)進(jìn)程正在執(zhí)行時(shí),你用鍵盤按Ctrl+c,就是給這個(gè)進(jìn)程發(fā)送了一個(gè)信號(hào)。進(jìn)程在捕捉到這個(gè)信號(hào)后會(huì)做相應(yīng)的動(dòng)作。
雖然信號(hào)是可以自定義的,但這并不能改變信號(hào)的局限性:不能跨LAN、信息量極其有限
。
在現(xiàn)代的分布式系統(tǒng)中,通常都是消息驅(qū)動(dòng):
即進(jìn)程受到某個(gè)消息后,通過對(duì)消息的內(nèi)容的分析然后做相應(yīng)的動(dòng)作。如果你把你的分布式系統(tǒng)設(shè)置成信號(hào)驅(qū)動(dòng)的,這就表示你收到一個(gè)信號(hào)就要做一個(gè)動(dòng)作而一個(gè)信號(hào)的本質(zhì)其實(shí)就是一個(gè)數(shù)字而已。這樣系統(tǒng)稍微大一點(diǎn)的話,系統(tǒng)將變得異常難以維護(hù);甚至在很多時(shí)候,信號(hào)驅(qū)動(dòng)是無法滿足我們的需求的。
因此現(xiàn)在我們一般也不用信號(hào)了。因此,請(qǐng)記住:
除非你有非常有說服力的理由,否則請(qǐng)用socket。
順便給你推薦個(gè)基于socket的輕量級(jí)的消息庫:ZeroMQ。
linux多線程詳解?
1.進(jìn)程是操作系統(tǒng)分配資源的基本單位。而線程通俗來講就是一個(gè)進(jìn)程中一個(gè)執(zhí)行流。
2.這里以串行與并行下載文件舉例,如果我們使用串行的方式去下載多個(gè)文件,那么得到的結(jié)果是,將這些文件逐個(gè)按個(gè)的下載,即上一個(gè)下載完成之后才會(huì)下載接下來的文件。
3.如果使用并行的方式下載,那么這些文件就會(huì)一次同時(shí)下載多個(gè)文件,而不是等待上一個(gè)下載完后才繼續(xù)下載接下來的,大大的提高了下載效率。
cpu多線程和jvm多線程?
一 cpu個(gè)數(shù)、核數(shù)、線程數(shù)的關(guān)系
cpu個(gè)數(shù):是指物理上,也及硬件上的核心數(shù);
核數(shù):是邏輯上的,簡單理解為邏輯上模擬出的核心數(shù);一個(gè)CPU核心數(shù)模擬出2線程的CPU
線程數(shù):是同一時(shí)刻設(shè)備能并行執(zhí)行的程序個(gè)數(shù),線程數(shù)=cpu個(gè)數(shù) * 核數(shù),及程數(shù)=cpu個(gè)數(shù)(2) * 核數(shù)(2)=4
Windows: wmic 然后 物理CPU數(shù) “cpu get NumberOfCores”, CPU核心數(shù) “cpu get NumberOfLogicalProcessors”
Linux:
查看CPU個(gè)數(shù) cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
查看核數(shù) cat /proc/cpuinfo| grep "cpu cores"| uniq
二 cpu線程數(shù)和Java多線程
(1) 線程是CPU級(jí)別的,單個(gè)線程同時(shí)只能在單個(gè)cpu線程中執(zhí)行
(2) Java多線程并不是由于cpu線程數(shù)為多個(gè)才稱為多線程,當(dāng)Java線程數(shù)大于cpu線程數(shù),操作系統(tǒng)使用時(shí)間片機(jī)制,采用線程調(diào)度算法,頻繁的進(jìn)行線程切換。
(3) 線程是操作系統(tǒng)最小的調(diào)度單位,進(jìn)程是資源(比如:內(nèi)存)分配的最小單位
(4)Java中的所有線程在JVM進(jìn)程中,CPU調(diào)度的是進(jìn)程中的線程
線程的調(diào)度是指按照特定的機(jī)制為多個(gè)線程分配CPU的使用權(quán)。有兩種調(diào)度模型:分時(shí)調(diào)度模型和搶占式調(diào)度模型
分時(shí)調(diào)度模型是指讓所有線程輪流獲得CPU的使用權(quán),并且平均分配每個(gè)線程占用CPU的時(shí)間片。
Java虛擬機(jī)采用搶占式調(diào)度模型,是指優(yōu)先讓可運(yùn)行池中處于就緒態(tài)的線程中優(yōu)先級(jí)高的占用CPU,如果可運(yùn)行池中線程的優(yōu)先級(jí)相同,那么就隨機(jī)選擇一個(gè)線程,使其占用CPU,處于運(yùn)行狀態(tài)的線程會(huì)一直執(zhí)行,直至它不得不放棄CPU,一個(gè)線程會(huì)因?yàn)橐韵略蚍艞塁PU:
(1)Java虛擬機(jī)讓當(dāng)前線程暫時(shí)放棄CPU,轉(zhuǎn)到就緒態(tài),使其他線程獲得運(yùn)行機(jī)會(huì)
(2)當(dāng)前線程因?yàn)槟承┰蚨幱谧枞麪顟B(tài)
(3)線程運(yùn)行結(jié)束
Java線程讓步:
3. Thread.yield()方法
就是說當(dāng)一個(gè)線程使用了這個(gè)方法之后,它就會(huì)把自己CPU執(zhí)行的時(shí)間讓掉,讓自己或者其它的線程運(yùn)行,注意是讓自己或者其他線程運(yùn)行(根據(jù)CPU的調(diào)度),并不是單純的讓給其他線程。
4.等待其他線程結(jié)束:join()
當(dāng)前運(yùn)行的線程可以調(diào)用另一個(gè)線程的join()方法,當(dāng)前運(yùn)行的線程將轉(zhuǎn)到阻塞狀態(tài),直至另一個(gè)線程運(yùn)行結(jié)束,它才會(huì)恢復(fù)運(yùn)行(阻塞恢復(fù)到就緒)
總結(jié)
以上是生活随笔為你收集整理的linux c++ 多线程(c linux 多线程)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jcg q8 固件_JCG学院开设了Ja
- 下一篇: 安卓天气预报和苹果天气预报哪个准(安卓天