『壹』 多進程OSPF及進程號的意義
在配置OSPF時,我們採用的是router ospf命令,在該命令後面需要加上這個OSPF進程的進程號(Process-Id),進程號用於在一台路由器上區分不同的OSPF進程。這就有點像人格分裂的感覺 —— 一個自然人有多種不同人格,每種人格之間相互獨立,互不影響。進程號的取值范圍是1-65535。
拓撲中,R1使用進程號10創建了一個OSPF進程,同時激活了自己的直連介面FE0/0,而R2使用進程號20創建了一個OSPF進程,同時也在自己的直連介面上激活了OSPF。雖然這兩個進程號不一樣,但是R1-R2之間的鄰居關系建立是完全沒有問題的。因為OSPF進程號只具有本地意義,路由器之間交互的所有OSPF報文中,都不會體現任何關於進程號的信息。進程號只在一台路由器上用於區分多個OSPF進程,因此對於R1而言,它並不關心它的直連OSPF鄰居R2使用的是什麼OSPF進程號,10也號,20也罷,這就有點像“自己的事自己知道就行“ -- 本地意義。
當然,在實際的網路部署中,除非有特定的需求,我們還是建議全網使用統一的進程號,雖然每台設備使用不同的進程號對OSPF的運行沒什麼影響,但是卻給網路的管理和維護帶來了多餘的成本,你不會這么乾的,對吧?
1. 多個OSPF進程
拓撲很有意思,在R2上,常規的做法是用一個進程號創建一個OSPF進程,同時將自己的兩個直連介面都宣告進這個OSPF進程,但是為了講解OSPF進程ID的本地意義,我這里在R2上使用兩個進程號分別創建了兩個OSPF進程,並且分別宣告了R2的兩個直連介面,換句話說,R2使用OSPF進程12與R1建立鄰居關系,使用OSPF進程23與R3建立OSPF鄰居關系。如此一來,R2在本地就有了兩個OSPF進程,使用進程號12及23進行區分。整個網路中也就出現了兩個OSPF域(OSPF Domain)。這兩個OSPF進程,都會各自從其鄰居R1和R3學習到OSPF路由,但是值得強調的是:
這兩個OSPF進程相互獨立和隔離(兩個OSPF Domain),兩個進程獨立維護各自的LSDB。換而言之R2通過OSPF進程12從R1學習到的OSPF路由(嚴格的說,應該是LSA),例如描述1.1.1.0/24的LSA,預設時不會傳遞到進程23的(這是因為在R2,這兩個OSPF進程互相獨立互相隔離),當然,從R3學習過來的OSPF路由,R2雖然自己能學習到,但是照樣不會傳遞給R1,這就好像,這兩個進程雖然都在R2上,但是彼此之間有著一道鴻溝,世界上最遙遠的距離,莫過於此啊。
再者,R2這兩個OSPF進程雖然說彼此隔離,但是都可以為R2自身貢獻路由,例如如果R1更新過來一條路由1.1.1.0/24,R3更新過來一條3.3.3.0/24,那麼在R2的全局路由表裡都是能看到這兩條路由的。但這兩條路由不會互相灌進對方的OSPF進程(造成的直接結果是R1沒有R3的路由,R3沒有R1的路由),除非 -- 對了,路由重發布,你懂的。
2. OSPF進程之間的路由重發布
同一台路由器上的不同OSPF進程相互獨立,各自維護自己的LSDB。如果要把一個OSPF進程內的路由注入到另一個進程中,就需要部署路由重發布,例如上圖所示,R2作為一台ASBR,要把進程12中的路由注入到進程23中,配置如上。當然,如果要實現全網路由互通,則還需要在OSPF進程12中,將進程23的路由重發布進來。
3. 什麼時候會使用不同的OSPF進程
我們知道一台路由器可以創建多個OSPF進程,而且進程之間相互隔離。一般情況下,當我們在做網路建設時,整個網路就是一個統一的路由選擇域,如果選用OSPF作為路由協議,則所有的OSPF路由器使用一個OSPF進程即可。
展示了一個大型企業的網路拓撲,R1、R2、R3及R4是省公司的設備,SW1、SW2及往下是市公司的設備,R5是區縣站點設備(實際上有多個區縣站點,此處只顯示了一個)。為了實現市公司與各區縣站點的網路互通,我們在市公司所有設備,以及區縣站點的所有路由器上都配置了OSPF並且進行了多區域的規劃。由於整個企業數據網路的規模較大,要想打通整個網路的路由,使用一個OSPF域直接從區縣站點往上拉到省公司,顯然是不靠譜的,一來整個域太大,路由前綴數量太多,二來OSPF的多區域設計在面對這么大規模網路的時候顯得還是有點力不從心,三來總公司並不希望看到分公司以及下面的子站點的路由明細,路由匯總勢必是要考慮的,加之對流量的走向還有嚴格的要求,策略部署上如何考慮?因此為省公司網路規劃了另外一個OSPF域,在省公司的邊界設備R3、R4上創建兩個OSPF進程,進程1面向總公司,進程2面向下面的市公司及區縣站點。兩個進程相互獨立不互相干擾,而R3及R4又能夠學習到省公司、分公司及各個區縣站點的路由,兩個OSPF域可以獨立規劃,域內Area的設計又變得更加寬松和靈活。
當然,省公司、總干以及地市公司是需要相互通信的,這時候由於省公司的網路屬於OSPF進程1,而市分公司及區縣站點的網路屬於OSPF進程2,相互獨立,為了把路由打通,就需要在R3和R4上執行OSPF進程之間的路由相互重發布。一旦把R3、R4設計為路由重發布的執行點,他倆瞬間就變得非常重要和牛逼了,因為在重發布的過程中,可以執行路由策略、可以做路由過濾,更可以做路由匯總,網路的.設計和規劃就變得非常有彈性了。
下面再來看多進程OSPF的另一個例子:
網路中,存在兩個不同的業務。生產及辦公,兩個業務各有自己的伺服器網路,兩台Router分別連接著這兩個業務的伺服器網路。而終端用戶則連接在SW上,現在終端用戶需要訪問各自業務的伺服器,那麼SW當然是需要有相應的路由的。我們希望將生產及辦公的業務進行隔離,但是這兩個業務的終端用戶又都是連接在SW上,如何隔離?很簡單,在SW上創建兩個OSPF進程,其中進程1用於生產業務,進程2用於辦公業務。在OSPF進程1中,激活VLAN10及VLAN20對應的SVI,並激活與SC-Router對接的三層介面;在OSPF進程2中,激活VLAN30、40對應的SCI,並激活與BG-Router對接的三層介面,如此一來辦公及生產伺服器網段的路由通過這兩個OSPF進程在SW上進行了隔離。
這的確是一種好方法,但是雖然OSPF進程是隔離的,SW的全局路由表中卻擁有者生產及辦公兩個業務的路由,也就是說兩個業務的路由實際上在SW這個點上是打通的,顯然不夠安全,如果有人從辦公網路登到辦公終端,然後再從辦公終端跳轉,去訪問生產伺服器就麻煩了。所以,我們又引入了另一個概念——VRF(Virtual Routing Forwarding,虛擬路由轉發),所謂的VRF你可以理解為虛擬設備,通過在SW上創建VRF實例,並且將生產的OSPF進程關聯到一個VRF實例中,從而徹底將生產路由與辦公路由進行隔離(辦公路由及業務跑在根設備上,生產路由及業務跑在VRF實例上,兩者完全隔離,可以想像為兩台SW)。
『貳』 多線程與多進程的命令應該寫在什麼位置
進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。
線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以並發執行。
『叄』 如何使用 pm2 部署 express 多進程
使用命令:
pm2 startOrReload process.json --env prod
在process.json中配置集群 多少個核心跑你的伺服器
『肆』 windows批處理 如何同時運行多個進程
部分exe在命令行啟動的話會佔用命令提示符(不清楚這之間的關系)
如果你這3個不是一定要按順序執行的話可以考慮調換順序
如果要按順序執行的話可以考慮把start命令的內容分別放到3個批處理裡面,然後由一個批處理分別執行這3個批處理達到效果
比如:
——以下為「批處理0.bat」的內容——
@echo off
start 批處理1.bat
start 批處理2.bat
start 批處理3.bat
————結束————
——以下為「批處理1.bat」的內容——
————結束————
……類推……
不過建議你試試這樣的命令格式:
cd "C:\redis-2.0.2"
start "redis" redis-server.exe redis.config
可以合並為一條:
start "redis" "C:\redis-2.0.2\redis-server.exe" redis.config
『伍』 如何使用gdb調試多進程
在2.5.60版Linux內核及以後,GDB對使用fork/vfork創建子進程的程序提供了follow-fork-mode選項來支持多進程調試。
follow-fork-mode的用法為:
set follow-fork-mode [parent|child]
parent: fork之後繼續調試父進程,子進程不受影響。
child: fork之後調試子進程,父進程不受影響。
因此如果需要調試子進程,在啟動gdb後:
(gdb) set follow-fork-mode child並在子進程代碼設置斷點。
此外還有detach-on-fork參數,指示GDB在fork之後是否斷開(detach)某個進程的調試,或者都交由GDB控制:
set detach-on-fork [on|off]
on: 斷開調試follow-fork-mode指定的進程。
off: gdb將控制父進程和子進程。follow-fork-mode指定的進程將被調試,另一個進程置於暫停(suspended)狀態。
注意,最好使用GDB 6.6或以上版本,如果你使用的是GDB6.4,就只有follow-fork-mode模式。
follow-fork-mode/detach-on-fork的使用還是比較簡單的,但由於其系統內核/gdb版本限制,我們只能在符合要求的系統上才能使用。而且,由於follow-fork-mode的調試必然是從父進程開始的,對於fork多次,以至於出現孫進程或曾孫進程的系統,例如上圖3進程系統,調試起來並不方便。
Attach子進程
眾所周知,GDB有附著(attach)到正在運行的進程的功能,即attach <pid>命令。因此我們可以利用該命令attach到子進程然後進行調試。
例如我們要調試某個進程RIM_Oracle_Agent.9i,首先得到該進程的pid
[root@tivf09 tianq]# ps -ef|grep RIM_Oracle_Agent.9i
nobody 6722 6721 0 05:57 ? 00:00:00 RIM_Oracle_Agent.9i
root 7541 27816 0 06:10 pts/3 00:00:00 grep -i rim_oracle_agent.9i通過pstree可以看到,這是一個三進程系統,oserv是RIM_Oracle_prog的父進程,RIM_Oracle_prog又是RIM_Oracle_Agent.9i的父進程。
[root@tivf09 root]# pstree -H 6722通過 pstree 察看進程
現在就可以調試了。一個新的問題是,子進程一直在運行,attach上去後都不知道運行到哪裡了。有沒有辦法解決呢?
一個辦法是,在要調試的子進程初始代碼中,比如main函數開始處,加入一段特殊代碼,使子進程在某個條件成立時便循環睡眠等待,attach到進程後在該代碼段後設上斷點,再把成立的條件取消,使代碼可以繼續執行下去。
至於這段代碼所採用的條件,看你的偏好了。比如我們可以檢查一個指定的環境變數的值,或者檢查一個特定的文件存不存在。以文件為例,其形式可以如下:
void debug_wait(char *tag_file)
{
while(1)
{
if (tag_file存在)
睡眠一段時間;
else
break;
}
}當attach到進程後,在該段代碼之後設上斷點,再把該文件刪除就OK了。當然你也可以採用其他的條件或形式,只要這個條件可以設置/檢測即可。
Attach進程方法還是很方便的,它能夠應付各種各樣復雜的進程系統,比如孫子/曾孫進程,比如守護進程(daemon process),唯一需要的就是加入一小段代碼。
GDB wrapper
很多時候,父進程 fork 出子進程,子進程會緊接著調用 exec族函數來執行新的代碼。對於這種情況,我們也可以使用gdb wrapper 方法。它的優點是不用添加額外代碼。
其基本原理是以gdb調用待執行代碼作為一個新的整體來被exec函數執行,使得待執行代碼始終處於gdb的控制中,這樣我們自然能夠調試該子進程代碼。
還是上面那個例子,RIM_Oracle_prog fork出子進程後將緊接著執行RIM_Oracle_Agent.9i的二進制代碼文件。我們將該文件重命名為RIM_Oracle_Agent.9i.binary,並新建一個名為RIM_Oracle_Agent.9i的shell腳本文件,其內容如下:
[root@tivf09 bin]# mv RIM_Oracle_Agent.9i RIM_Oracle_Agent.9i.binary
[root@tivf09 bin]# cat RIM_Oracle_Agent.9i
#!/bin/sh
gdb RIM_Oracle_Agent.binary當fork的子進程執行名為RIM_Oracle_Agent.9i的文件時,gdb會被首先啟動,使得要調試的代碼處於gdb控制之下。
『陸』 如何理解「多進程」,「多任務」的概念
多進程可以理解為運行多個程序 例如WINDOWS就能管理多個進程,在任務管理器裡面能看到
多任務可以理解我同時執行多個任務,但實際是不是同完執行多個任務,而是CPU處理速度太快了讓我們感覺是同時執行多個任務。
多線程可以理解為一個程序同時執行多段代碼,在同一個程序內同時操多個功能;例如你點了應用按鈕之後再去點其它的按鈕,兩個命令同時運行,如個是單線程的話點了只能等這個操作完成之後,才能進行其它的操作,如果同時操作會出現末響應的的提示,他和多任務非常的相似。
『柒』 如何運行多進程Docker容器
運行多進程Docker容器的方法如下:
1、使用Shell腳本依次啟動Kubernetes的各個組件即可。
以下為start-kubernetes.sh
『捌』 TCP和UDP中怎麼加入多線程、多進程
1、UDP
UDP(User Datagram Protocol,用戶數據報協議)不提供復雜的控制機制,利用IP提供面向無連接的通信服務。它是將應用程序發來的數據在收到的那一刻,立即按照原樣發送到網路上的一種機制。
UDP的特點
UDP是一個非連接的協議,傳輸數據之前,源端和終端不建立連接,當它想傳送時就簡單地去抓取來自應用程序的數據,並盡可能快地把它扔到網路上。在發送端,UDP傳送數據的速度僅僅是受應用程序生成數據的速度、計算機的能力和傳輸帶寬的限制;在接收端,UDP把每個消息段放在隊列中,應用程序每次從隊列中讀一個消息段;由於傳輸數據不建立連接,因此也就不需要維護連接狀態,包括收發狀態等,因此一台服務機可同時向多個客戶機傳輸相同的消息;UDP信息包的標題很短,只有8個位元組,相對於TCP的20個位元組信息包的額外開銷很小;UDP使用盡最大努力交付,即不保證可靠交付,因此主機不需要維持復雜的鏈接狀態表(有許多參數);UDP是面向報文的。發送方的UDP對應用程序交下來的報文,在添加首部後就向下交付給IP層。既不拆分,也不合並,而是保留這些報文的邊界,因此,應用程序需要選擇合適的報文大小。
2、TCP
TCP(Transmission Control Protocol,傳輸控制協議)是面向連接的協議,也可是說是對「傳輸、發送、通信」進行「控制」的協議。
TCP作為一種面向有連接的協議,只有在確認通信對端存在時才會發送數據,從而可以控制通信流量的浪費。且TCP實現了數據傳輸時各種控制功能,可以進行丟包時的重發控制,還可以對次序亂掉的分包進行順序控制。TCP通過檢驗和、序列號、確認應答、重發控制、連接管理以及窗口控制等機制實現可靠性傳輸。
TCP與UDP的區別
TCP面向連接(如打電話要先撥號建立連接)。UDP是無連接的,即發送數據之前不需要建立連接;TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達。UDP盡最大努力交付,即不保證可靠交付;TCP面向位元組流,實際上是TCP把數據看成一連串無結構的位元組流。UDP是面向報文的;每一條TCP連接只能是點到點的。UDP支持一對一、一對多、多對一和多對多的交互通信;對系統資源的要求TCP較多,UDP少。TCP首部開銷20位元組,UDP的首部開銷小,只有8個位元組;TCP的邏輯通信信道是全雙工的可靠信道。UDP則是不可靠信道。
TCP建立連接的3次握手過程
主機A通過向主機B發送一個含有同步序列號的標志位的數據段給主機B,向主機B請求建立連接,通過這個數據段,主機A告訴主機B兩件事:我想要和你通信;你可以用哪個序列號作為起始數據段來回應我;主機B收到主機A的請求後,用一個帶有確認應答(ACK)和同步序列號(SYN)標志位的數據段響應主機A,也告訴主機A兩件事:我已經收到你的請求了,你可以傳輸數據了;你要用哪個序列號作為起始數據段來回應我;主機A收到這個數據段後,再發送一個確認應答,確認已收到主機B的數據段:「我已收到回復,我現在要開始傳輸實際數據了」。
這樣3次握手就完成了,主機A和主機B就可以傳輸數據了。
TCP斷開連接的4次確認
當主機A完成數據傳輸後,將控制位FIN置1,提出停止TCP連接的請求;主機B收到FIN後對其作出響應,確認這一方向上的TCP連接將關閉,將ACK置1;由B端再提出反方向的關閉請求,將FIN置1;主機A對主機B的請求進行確認,將ACK置1,雙方向的關閉結束。
由TCP的3次握手和4次斷開確認可以看出,TCP使用面向連接的通信方式,大大提高了數據通信的可靠性,使發送數據端和接收端在數據正式傳輸前就有了交互,為數據正式傳輸打下了可靠的基礎。
我們經常使用「ping」命令來測試兩台主機之間TCP/IP通信是否正常,其實「ping」命令的原理就是向對方主機發送UDP數據包,然後對方主機確認收到數據包,如果數據包是否到達的消息及時反饋回來,那麼網路就是通的。
『玖』 如何使用gdb調試多進程
在大多數系統,gdb對使用fork創建的進程沒有進行特別的支持。當父進程使用fork創建子進程,gdb仍然只會調試父進程,而子進程沒有得到控制和調試。這個時候,如果你在子進程執行到的代碼中設置了斷點,那麼當子進程執行到這個斷點的時候,會產生一個SIGTRAP的信號,如果沒有對此信號進行捕捉處理,就會按默認的處理方式處理——終止進程。
當然,你可以使用時間延遲的方法,在子進程fork出來之後,使用Sleep函數等待一段時間再運行,在這段時間中你使用ps找到該進程,然後使用Attach方法把該進程附加到gdb中,從而達到可以調試子進程的目的。
在一部分系統中(我使用的是基於2.6內核的CentOS,支持follow-fork和detach-on-fork模式),比如HP-UX11.x之後的版本,Linux2.5.60之後的版本,可以使用以下的方法來達到方便的進行多進程調試功能。
默認情況下,父進程fork一個子進程,gdb只會繼續調試父進程而不會管子進程的運行。
如果你想跟蹤子進程進行調試,可以使用set follow-fork-mode mode來設置fork跟隨模式。
set follow-fork-mode 所帶的mode參數可以是以下的一種:
parent
gdb只跟蹤父進程,不跟蹤子進程,這是默認的模式。
child
gdb在子進程產生以後只跟蹤子進程,放棄對父進程的跟蹤。
進入gdb以後,我們可以使用show follow-fork-mode來查看目前的跟蹤模式。
可以看到目前使用的模式是parent。
然而,有的時候,我們想同時調試父進程和子進程,以上的方法就不能滿足了。Linux提供了set detach-on-fork mode命令來供我們使用。其使用的mode可以是以下的一種:
on
只調試父進程或子進程的其中一個(根據follow-fork-mode來決定),這是默認的模式。
off
父子進程都在gdb的控制之下,其中一個進程正常調試(根據follow-fork-mode來決定)
另一個進程會被設置為暫停狀態。
同樣,show detach-on-fork顯示了目前是的detach-on-fork模式,如上圖。
以上是調試fork產生子進程的情況,但是如果子進程使用exec系統函數而裝載了新程序執行呢?——我們使用set follow-exec-mode mode提供的模式來跟蹤這個exec裝載的程序。mode可以是以下的一種:
new 當發生exec的時候,如果這個選項是new,則新建一個inferior給執行起來的子進程,而父進程的inferior仍然保留,當前保留的inferior的程序狀態是沒有執行。
same 當發生exec的時候,如果這個選項是same(默認值),因為父進程已經退出,所以自動在執行exec的inferior上控制子進程。
我們可以使用apue裡面第8章的例子代碼來做測試:
#include "apue.h"
intglob = 6;/* external variable in initialized data */
charbuf[] = "a write to stdout\n";
int
main(void)
{
intvar;/* automatic variable on the stack */
pid_tpid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork\n");/* we don't flush stdout */
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {/* child */
glob++;/* modify variables */
var++;
} else {
sleep(2);/* parent */
}
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}