2016年9月29日 星期四

[windows]網管常用的網路指令

我們在 Windows 2000 的 cmd shell 下,輸入 netsh就出來:netsh> 提示號,
輸入 int ip 就顯示:
interface ip>
然後輸入 dump ,我們就可以看到當前系統的網路配置:


# ---------------------------------- 
# Interface IP Configuration 
# ---------------------------------- 
pushd interface ip 

# Interface IP Configuration for "Local Area Connection" 

set address name = "Local Area Connection" source = static addr = 192.168.1.168 
mask = 255.255.255.0 
add address name = "Local Area Connection" addr = 192.1.1.111 mask = 255.255.255.0 
set address name = "Local Area Connection" gateway = 192.168.1.100 gwmetric = 1 
set dns name = "Local Area Connection" source = static addr = 202.96.209.5 
set wins name = "Local Area Connection" source = static addr = none 

popd 
# End of interface IP configuration

上面介紹的是通過交互方式操作的一種辦法。我們可以直接輸入指令:


"netsh interface ip add address "Local Area Connection" 10.0.0.2 255.0.0.0"來增加 IP 位址。

如果不知道語法,不要緊的哦!

在提示號下,輸入 ? 就可以找到答案了。方便不方便啊?
原來微軟的東西裡面,也有那麼一些讓人喜歡的玩意兒。可惜,之至者甚少啊!

Windows網路指令行程序
這部分包括:

使用 ipconfig /all 檢視配置
使用 ipconfig /renew 重新整理配置
使用 ipconfig 管理 DNS 和 DHCP 類別 ID
使用 Ping 測試連接
使用 Arp 解決硬體位址問題
使用 nbtstat 解決 NetBIOS 名稱問題
使用 netstat 顯示連接統計
使用 tracert 跟蹤網路連接
使用 pathping 測試路由器
使用 ipconfig /all 檢視配置
發現和解決 TCP/IP 網路問題時,先檢查出現問題的電腦上的 TCP/IP 配置。可以
使用 ipconfig 指令獲得主機配置資訊,包括 IP 位址、子網掩碼和預設網關。

注意

對於 Windows 95 和 Windows 98 的客戶端機,請使用 winipcfg 指令而不是 ipconfi
g 指令。
使用帶 /all 選項的 ipconfig 指令時,將給出所有接頭的詳細配置報告,包括任何已配置的串行連接阜。使用 ipconfig /all,可以將指令輸出重定向到某個文件,並將輸出貼上到其他我的文件中。也可以用該輸出驗證網路上每台電腦的 TCP/IP 配置,或者進一步調查 TCP/IP 網路問題。

例如,如果電腦配置的 IP 位址與現有的 IP 位址重複,則子網掩碼顯示為 0.0.0.0。

下面的範例是 ipconfig /all 指令輸出,該電腦配置成使用 DHCP 伺服器動態配置TCP/IP,並使用 WINS 和 DNS 伺服器解析名稱。


Windows 2000 IP Configuration 

Node Type.. . . . . . . . : Hybrid 
IP Routing Enabled.. . . . : No 
WINS Proxy Enabled.. . . . : No 

Ethernet adapter Local Area Connection: 

Host Name.. . . . . . . . : corp1.microsoft.com 
DNS Servers . . . . . . . : 10.1.0.200 
Description. . . . . . . : 3Com 3C90x Ethernet Adapter 
Physical Address. . . . . : 00-60-08-3E-46-07 
DHCP Enabled.. . . . . . . : Yes 
Autoconfiguration Enabled.: Yes 
IP Address. . . . . . . . . : 192.168.0.112 
Subnet Mask. . . . . . . . : 255.255.0.0 
Default Gateway. . . . . . : 192.168.0.1 
DHCP Server. . . . . . . . : 10.1.0.50 
Primary WINS Server. . . . : 10.1.0.101 
Secondary WINS Server. . . : 10.1.0.102 
Lease Obtained.. . . . . . : Wednesday, September 02, 1998 10:32:13 AM 
Lease Expires.. . . . . . : Friday, September 18, 1998 10:32:13 AM

如果 TCP/IP 配置沒有問題,下一步測試能夠連線到 TCP/IP 網路上的其他主機。

使用 ipconfig /renew 重新整理配置解決 TCP/IP 網路問題時,先檢查遇到問題的電腦上的 TCP/IP 配置。如果電腦啟用 DHCP 並使用 DHCP 伺服器獲得配置,請使用 ipconfig /renew 指令開始重新整理租約。

使用 ipconfig /renew 時,使用 DHCP 的電腦上的所有網路卡(除了那些手動配置的橋接器)都盡量連線到 DHCP 伺服器,更新現有配置或者獲得新配置。

也可以使用帶 /release 選項的 ipconfig 指令立即釋放主機的當前 DHCP 配置。有關 DHCP 和租用程序的詳細資料,請參閱客戶端機如何獲得配置。

注意

對於啟用 DHCP 的 Windows 95 和 Windows 98 客戶,請使用 winipcfg 指令的 release 和 renew 選項,而不是 ipconfig /release 和 ipconfig /renew 指令,手動釋放或更新客戶的 IP 配置租約。使用 ipconfig 管理 DNS 和 DHCP 類別 ID也可以使用 ipconfig 指令:

顯示或重置 DNS 緩衝。
詳細資料,請參閱使用 ipconfig 檢視或重置客戶解析程序緩衝。

重新整理已註冊的 DNS 名稱。
詳細資料,請參閱使用 ipconfig 更新 DNS 客戶註冊。

顯示橋接器的 DHCP 類別 ID。
詳細資料,請參閱顯示客戶端機上的 DHCP 類別 ID 信息。

設定橋接器的 DHCP 類別 ID。
詳細資料,請參閱設定客戶端機上的 DHCP 類別 ID 信息。

使用 Ping 測試連接
Ping 指令有助於驗證 IP 級的連通性。發現和解決問題時,可以使用 Ping 向目標主機名或 IP 位址傳送 ICMP 回應請求。需要驗證主機能否連線到 TCP/IP 網路和網路資源時,請使用 Ping。也可以使用 Ping 隔離網路硬體問題和不相容配置。

通常最好先用 Ping 指令驗證本機電腦和網路主機之間的路由是否存在,以及要連接的網路主機的 IP 位址。Ping 目標主機的 IP 位址看它是否回應,如下:


ping IP_address

使用 Ping 時應該執行以下步驟:

Ping 環回位址驗證是否在本機電腦上安裝 TCP/IP 以及配置是否正確。
ping 127.0.0.1

Ping 本機電腦的 IP 位址驗證是否正確地增加到網路。
ping IP_address_of_local_host

Ping 預設網關的 IP 位址驗證預設網關是否執行以及能否與本機網路上的本機主機通訊。
ping IP_address_of_default_gateway

Ping 遠端主機的 IP 位址驗證能否通過路由器通訊。
ping IP_address_of_remote_host

Ping 指令用 Windows 套接字樣式的名稱解析將電腦名稱解析成 IP 位址,所以如果用位址成功,但是用名稱 Ping 失敗,則問題出在位址或名稱解析上,而不是網路連通性的問題。詳細資料,請參閱使用 Arp 解決硬體位址問題。

如果在任何點上都無法成功地使用 Ping,請驗證:

安裝和配置 TCP/IP 之後重新啟動電腦。
「Internet 傳輸協定 (TCP/IP) 屬性內容」對話視窗「一般」選擇項上的本機電腦的 IP 位址有效而且正確。
啟用 IP 路由,並且路由器之間的鏈路是可用的。
您可以使用 Ping 指令的不同選項來指定要使用的資料包大小、要傳送多少資料包、是否記錄用過的路由、要使用的生存時間 (TTL) 值以及是否設定「不分段」標誌。可以鍵入 ping -? 檢視這些選項。

下例說明如何向 IP 位址 172.16.48.10 傳送兩個 Ping,每個都是 1,450 字元:


C:>ping -n 2 -l 1450 172.16.48.10 
Pinging 172.16.48.10 with 1450 bytes of data: 

Reply from 172.16.48.10:bytes=1450 time<10ms TTL=32 
Reply from 172.16.48.10:bytes=1450 time<10ms TTL=32 

Ping statistics for 157.59.8.1: 
Packets:Sent = 2, Received = 2, Lost = 0 (0% loss), 
Approximate roundtrip times in milli-seconds: 
Minimum = 0ms, Maximum = 10ms, Average = 2ms

預設情況下,在顯示「請求超時」之前,Ping 等待 1,000 毫秒(1 秒)的時間讓每個回應返回。如果通過 Ping 探測的遠端系統經過長時間延遲的鏈路,如衛星鏈路,則回應可能會花更長的時間才能返回。可以使用 -w (等待)選項指定更長時間的超時。

使用 Arp 解決硬體位址問題
「位址解析傳輸協定 (ARP)」允許主機搜尋同一物理網路上的主機的媒體訪問控制位址,如果給出後者的 IP 位址。為使 ARP 更加有效,每個電腦緩衝 IP 到媒體訪問控制位址映射消除重複的 ARP 廣播請求。

可以使用 arp 指令檢視和修改本機電腦上的 ARP 表項。arp 指令對於檢視 ARP 緩衝和解決位址解析問題非常有用。

詳細資料,請參閱檢視「位址解析傳輸協定 (ARP)」緩衝和增加靜態 ARP 緩衝項目。

使用 nbtstat 解決 NetBIOS 名稱問題
TCP/IP 上的 NetBIOS (NetBT) 將 NetBIOS 名稱解析成 IP 位址。TCP/IP 為 NetBIOS 名稱解析提供了很多選項,包括本機緩衝搜尋、WINS 伺服器查詢、廣播、DNS 伺服器查詢以及 Lmhosts 和主機文件搜尋。

Nbtstat 是解決 NetBIOS 名稱解析問題的有用工具。可以使用nbtstat 指令刪除或更正預載入的項目:

nbtstat -n 顯示由伺服器或重定向器之類的程序在系統上本機註冊的名稱。
nbtstat -c 顯示 NetBIOS 名稱緩衝,包含其他電腦的名稱對位址映射。
nbtstat -R 清除名稱緩衝,然後從 Lmhosts 文件重新載入。
nbtstat -RR 釋放在 WINS 伺服器上註冊的 NetBIOS 名稱,然後重新整理它們的註冊。
nbtstat -a name 對 name 指定的電腦執行 NetBIOS 橋接器狀態指令。橋接器狀態指令將返回電腦的本機 NetBIOS 名稱表,以及橋接器的媒體訪問控制位址。
nbtstat -S 列出當前的 NetBIOS 會話及其狀態(包括統計),如下例所顯示:


NetBIOS connection table 

Local name State In/out Remote Host Input Output 
-------------------------------------------------- 
CORP1 <00> Connected Out CORPSUP1<20> 6MB 5MB 
CORP1 <00> Connected Out CORPPRINT<20> 108KB 116KB 
CORP1 <00> Connected Out CORPSRC1<20> 299KB 19KB 
CORP1 <00> Connected Out CORPEMAIL1<20> 324KB 19KB 
CORP1 <03> Listening

使用 netstat 顯示連接統計
可以使用 netstat 指令顯示傳輸協定統計信息和當前的 TCP/IP 連接。netstat -a 指令將顯示所有連接,而 netstat -r 顯示路由表和活動連接。netstat -e 指令將顯示Ethernet 統計信息,而 netstat -s 顯示每個傳輸協定的統計信息。如果使用 netstat -n,則不能將位址和連接阜號轉換成名稱。下面是 netstat 的輸出示例:


C:>netstat -e 
Interface Statistics 

Received Sent 
Bytes 3995837940 47224622 
Unicast packets 120099 131015 
Non-unicast packets 7579544 3823 
Discards 0 0 
Errors 0 0 
Unknown protocols 363054211 

C:>netstat -a 

Active Connections 

Proto Local Address Foreign Address State 
TCP CORP1:1572 172.16.48.10:nbsession ESTABLISHED 
TCP CORP1:1589 172.16.48.10:nbsession ESTABLISHED 
TCP CORP1:1606 172.16.105.245:nbsession ESTABLISHED 
TCP CORP1:1632 172.16.48.213:nbsession ESTABLISHED 
TCP CORP1:1659 172.16.48.169:nbsession ESTABLISHED 
TCP CORP1:1714 172.16.48.203:nbsession ESTABLISHED 
TCP CORP1:1719 172.16.48.36:nbsession ESTABLISHED 
TCP CORP1:1241 172.16.48.101:nbsession ESTABLISHED 
UDP CORP1:1025 *:* 
UDP CORP1:snmp *:* 
UDP CORP1:nbname *:* 
UDP CORP1:nbdatagram *:* 
UDP CORP1:nbname *:* 
UDP CORP1:nbdatagram *:* 

C:>netstat -s 
IP Statistics 

Packets Received = 5378528 
Received Header Errors = 738854 
Received Address Errors = 23150 
Datagrams Forwarded = 0 
Unknown Protocols Received = 0 
Received Packets Discarded = 0 
Received Packets Delivered = 4616524 
Output Requests = 132702 
Routing Discards = 157 
Discarded Output Packets = 0 
Output Packet No Route = 0 
Reassembly Required = 0 
Reassembly Successful = 0 
Reassembly Failures = 
Datagrams Successfully Fragmented = 0 
Datagrams Failing Fragmentation = 0 
Fragments Created = 0 

ICMP Statistics 
Received Sent 
Messages 693 4 
Errors 0 0 
Destination Unreachable 685 0 
Time Exceeded 0 0 
Parameter Problems 0 0 
Source Quenches 0 0 
Redirects 0 0 
Echoes 4 0 
Echo Replies 0 4 
Timestamps 0 0 
Timestamp Replies 0 0 
Address Masks 0 0 
Address Mask Replies 0 0 

TCP Statistics 

Active Opens = 597 
Passive Opens = 135 
Failed Connection Attempts = 107 
Reset Connections = 91 
Current Connections = 8 
Segments Received = 106770 
Segments Sent = 118431 
Segments Retransmitted = 461 

UDP Statistics 

Datagrams Received = 4157136 
No Ports = 351928 
Receive Errors = 2 
Datagrams Sent = 13809

使用 tracert 跟蹤網路連接
Tracert(跟蹤路由)是路由跟蹤實用程序,用於確定 IP 資料報訪問目標所採取的路徑。Tracert 指令用 IP 生存時間 (TTL) 字段和 ICMP 錯誤消息來確定從一個主機到網路上其他主機的路由。

Tracert 工作原理
通過向目標傳送不同 IP 生存時間 (TTL) 值的「Internet 控制消息傳輸協定 (ICMP)」回應資料包,Tracert 診斷程序確定到目標所採取的路由。要求路徑上的每個路由器在轉發資料包之前至少將資料包上的 TTL 遞減 1。資料包上的 TTL 減為 0 時,路由器應該將「ICMP 已超時」的消息發回源系統。

Tracert 先傳送 TTL 為 1 的回應資料包,並在隨後的每次傳送程序將 TTL 遞增 1,直到目標回應或 TTL 達到最大值,從而確定路由。通過檢查中間路由器發回的「ICMP 已超時」的消息確定路由。某些路由器不經詢問直接丟棄 TTL 過期的資料包,這在Tracert 實用程序中看不到。

Tracert 指令按順序列印出返回「ICMP 已超時」消息的路徑中的近端路由器接頭列表。如果使用 -d 選項,則 Tracert 實用程序不在每個 IP 位址上查詢 DNS。

在下例中,資料包必須通過兩個路由器(10.0.0.1 和 192.168.0.1)才能到達主機
172.16.0.99。主機的預設網關是 10.0.0.1,192.168.0.0 網路上的路由器的 IP 地
址是 192.168.0.1。


C:>tracert 172.16.0.99 -d 
Tracing route to 172.16.0.99 over a maximum of 30 hops 
1 2s 3s 2s 10,0.0,1 
2 75 ms 83 ms 88 ms 192.168.0.1 
3 73 ms 79 ms 93 ms 172.16.0.99 
Trace complete.


用 tracert 解決問題
可以使用 tracert 指令確定資料包在網路上的停止位置。下例中,預設網關確定 19
2.168.10.99 主機沒有有效路徑。這可能是路由器配置的問題,或者是 192.168.10.
0 網路不存在(錯誤的 IP 位址)。


C:>tracert 192.168.10.99 


Tracing route to 192.168.10.99 over a maximum of 30 hops 

1 10.0.0.1 reportsestination net unreachable. 

Trace complete.

Tracert 實用程序對於解決大網路問題非常有用,此時可以採取幾條路徑到達同一個
點。

Tracert 指令行選項
Tracert 指令支持多種選項,如下表所顯示。

tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name

選項 描述
-d 指定不將 IP 位址解析到主機名稱。
-h maximum_hops 指定躍點數以跟蹤到稱為 target_name 的主機的路由。
-j host-list 指定 Tracert 實用程序資料包所採用路徑中的路由器接頭列表。
-w timeout 等待 timeout 為每次回復所指定的毫秒數。
target_name 目標主機的名稱或 IP 位址。

詳細資料,請參閱使用 tracert 指令跟蹤路徑。

使用 pathping 測試路由器
pathping 指令是一個路由跟蹤工具,它將 ping 和 tracert 指令的功能和這兩個工具所不提供的其他信息結合起來。pathping 指令在一段時間內將資料包傳送到到達最終目標的路徑上的每個路由器,然後關於資料包的電腦結果從每個躍點返回。由於指令顯示資料包在任何給定路由器或連接上丟失的程度,因此可以很容易地確定可能導致網路問題的路由器或連接。某些選項是可用的,如下表所顯示。

選項 名稱 功能
-n Hostnames 不將位址解析成主機名。
-h Maximum hops 搜尋目標的最大躍點數。
-g Host-list 沿著路由列表釋放源路由。
-p Period 在 ping 之間等待的毫秒數。
-q Num_queries 每個躍點的查詢數。
-w Time-out 為每次回復所等待的毫秒數。
-T Layer 2 tag 將第 2 層優先級標記(例如,對於 IEEE 802.1p)連線到資料包並將它傳送到路徑中的每個網路設備。這有助於標識沒有正確配置第 2 層優先級的網路設備。-T 開關用於測試服務質量 (QoS) 連通性。
-R RSVP isbase Che檢查以確定路徑中的每個路由器是否支持「資源保留傳輸協定 (RSVP)」,此傳輸協定允許主機為資料流保留一定量的帶寬。 -R 開關用於測試服務質量 (QoS) 連通性。

預設的躍點數是 30,並且超時前的預設等待時間是 3 秒。預設時間是 250 毫秒,並且沿著路徑對每個路由器進行查詢的次數是 100。

以下是典型的 pathping 報告。躍點列表後所編輯的統計信息表明在每個獨立路由器上資料包丟失的情況。


D:> pathping -n msw 

Tracing route to msw [7.54.1.196] 
over a maximum of 30 hops: 
0 172.16.87.35 
1 172.16.87.218 
2 192.68.52.1 
3 192.68.80.1 
4 7.54.247.14 
5 7.54.1.196 

Computing statistics for 125 seconds... 
Source to Here This Node/Link 
Hop RTT Lost/Sent = Pct Lost/Sent = Pct Address 
0 172.16.87.35 
0/ 100 = 0% | 
1 41ms 0/ 100 = 0% 0/ 100 = 0% 172.16.87.218 
13/ 100 = 13% | 
2 22ms 16/ 100 = 16% 3/ 100 = 3% 192.68.52.1 
0/ 100 = 0% | 
3 24ms 13/ 100 = 13% 0/ 100 = 0% 192.68.80.1 
0/ 100 = 0% | 
4 21ms 14/ 100 = 14% 1/ 100 = 1% 10.54.247.14 
0/ 100 = 0% | 
5 24ms 13/ 100 = 13% 0/ 100 = 0% 10.54.1.196 

Trace complete.

當執行 pathping 時,在測試問題時首先檢視路由的結果。此路徑與 tracert 指令所顯示的路徑相同。然後 pathping 指令對下一個 125 毫秒顯示忙消息(此時間根據躍點計數變化)。在此期間,pathping 從以前列出的所有路由器和它們之間的連接之間收集信息。在此期間結束時,它顯示測試結果。

最右邊的兩欄 This Node/Link Lost/Sent=Pct 和 Address 包含的信息最有用。172.16.87.218(躍點 1)和 192.68.52.1(躍點 2)丟失 13% 的資料包。 所有其他連接工作正常。在躍點 2 和 4 中的路由器也丟失尋址到它們的資料包(如 This Node /Link 欄中所顯示),但是該丟失不會影響轉發的路徑。

對連接顯示的丟失率(在最右邊的欄中標記為 |)表明沿路徑轉發丟失的資料包。該丟失表明連接阻塞。對路由器顯示的丟失率(通過最右邊欄中的 IP 位址顯示)表明這些路由器的 CPU 可能超負荷執行。這些阻塞的路由器可能也是端對端問題的一個因素,尤其是在軟體路由器轉發資料包時。 

2016年9月18日 星期日

2016年9月14日 星期三

[轉] Ubuntu Linux 環境變量PATH設置


Ubuntu Linux系統環境變量配置文件: /etc/profile : 在登錄時,操作系統定制用戶環境時使用的第一個文件 ,此文件为系統的每個用戶設置環境信息,當用戶第一次登錄時,該文件被執行

Ubuntu Linux系統環境變量配置文件: 
/etc/profile : 在登錄時,操作系統定制用戶環境時使用的第一個文件 ,此文件为系統的每個用戶設置環境信息,當用戶第一次登錄時,該文件被執行。 

/etc /environment : 在登錄時操作系統使用的第二個文件, 系統在讀取你自己的profile前,設置環境文件的環境變量。 

~/.profile :  在登錄時用到的第三個文件 是.profile文件,每個用戶都可使用該文件輸入專用於自己使用的shell信息,當用戶登錄時,該文件僅僅執行一次!默認情況下,他設置一些環境變量,執行用戶的.bashrc文件。 

/etc/bashrc : 为每一個運行bash shell的用戶執行此文件.當bash shell被打開時,該文件被讀取. 

~/.bashrc : 該文件包含專用於你的bash shell的bash信息,當登錄時以及每次打開新的shell時,該該文件被讀取。 



PASH環境變量的設置方法: 

方法一:用戶主目錄下的.profile或.bashrc文件(推薦) 

登錄到你的用戶(非root),在終端輸入: 
$ sudo gedit ~/.profile(or .bashrc) 
可以在此文件末尾加入PATH的設置如下: 
export PATH=”$PATH:your path1:your path2 ...” 
保存文件,注銷再登錄,變量生效。 
該方式添加的變量只對當前用戶有效。 

方法二:系統目錄下的profile文件(謹慎) 

在系統的etc目錄下,有一個profile文件,編輯該文件: 
$ sudo gedit /etc/profile 
在最後加入PATH的設置如下: 
export PATH=”$PATH:your path1:your path2 ...” 
該文件編輯保存後,重启系統,變量生效。 
該方式添加的變量對所有的用戶都有效。 

方法三:系統目錄下的 environment 文件(謹慎) 

在系統的etc目錄下,有一個environment文件,編輯該文件: 
$ sudo gedit /etc/environment 
找到以下的 PATH 變量: 
PATH="<......>" 
修改該 PATH 變量,在其中加入自己的path即可,例如: 
PATH="<......>:your path1:your path2 …" 
各個path之間用冒號分割。該文件也是重启生效,影響所有用戶。 
注意這裏不是添加export PATH=… 。 

方法四:直接在終端下輸入 

$ sudo export PATH="$PATH:your path1:your path2 …" 
這種方式變量立即生效,但用戶注銷或系統重启後設置變成無效,适合臨時變量的設置。 


注 意:方法二和三的修改需要謹慎,尤其是通過root用戶修改,如果修改錯誤,將可能導致一些嚴重的系統錯誤。因此筆者推薦使用第一種方法。另外嵌入式 Linux的開發最好不要在root下進行(除非你對Linux已經非常熟悉了!!),以免因为操作不當導致系統嚴重錯誤。 

下面是一個對environment文件錯誤修改導致的問題以及解决方法示例: 

問題:因为不小心在 etc/environment裏設在環境變量導致無法登錄 
提示:不要在 etc/environment裏設置 export PATH這样會導致重启後登錄不了系統 
解决方法: 
在登錄界面 alt +ctrl+f1進入命令模式,如果不是root用戶需要鍵入(root用戶就不許這麼罗嗦,gedit編輯會不可顯示) 
/usr/bin/sudo /usr/bin/vi /etc/environment 
光標移到export PATH** 行,連續按 d兩次刪除該行; 
輸入:wq保存退出; 
然後鍵入/sbin/reboot重启系統(可能會提示need to boot,此時直接power off) 

Ubuntu 14.04設定網路連線

http://blog.xuite.net/yh96301/blog/242434403-Ubuntu+14.04%E8%A8%AD%E5%AE%9A%E7%B6%B2%E8%B7%AF%E9%80%A3%E7%B7%9A%E7%82%BA%E5%9B%BA%E5%AE%9AIP

2016年9月13日 星期二

2016年9月9日 星期五

linux command

- Touch all files and subdirectories (recursive touch)
       find . -exec touch {} \; 

2016年9月8日 星期四

[轉] pid,tid,真實pid的使用

1、pid,tid,真實pid的使用

進程pid: getpid()                 
線程tid: pthread_self()     //進程內唯一,但是在不同進程則不唯一。
線程pid: syscall(SYS_gettid)     //系統內是唯一的

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/syscall.h>

struct message
{
    int i;
    int j;
};

void *hello(struct message *str)
{
    printf("child, the tid=%lu, pid=%d\n",pthread_self(),syscall(SYS_gettid));
    printf("the arg.i is %d, arg.j is %d\n",str->i,str->j);
    printf("child, getpid()=%d\n",getpid());
    while(1);
}

int main(int argc, char *argv[])
{
    struct message test;
    pthread_t thread_id;
    test.i=10;
    test.j=20;
    pthread_create(&thread_id,NULL,hello,&test);
    printf("parent, the tid=%lu, pid=%d\n",pthread_self(),syscall(SYS_gettid));
    printf("parent, getpid()=%d\n",getpid());
    pthread_join(thread_id,NULL);
    return 0;
}

getpid()得到的是進程的pid,在內核中,每個線程都有自己的PID,要得到線程的PID,必須用syscall(SYS_gettid);
pthread_self函數獲取的是線程ID,線程ID在某進程中是唯一的,在不同的進程中創建的線程可能出現ID值相同的情況。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>

void *thread_one()
{
    printf("thread_one:int %d main process, the tid=%lu,pid=%ld\n",getpid(),pthread_self(),syscall(SYS_gettid));
}

void *thread_two()
{
    printf("thread two:int %d main process, the tid=%lu,pid=%ld\n",getpid(),pthread_self(),syscall(SYS_gettid));
}

int main(int argc, char *argv[])
{
    pid_t pid;
    pthread_t tid_one,tid_two;
    if((pid=fork())==-1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if(pid==0)
    {
        pthread_create(&tid_one,NULL,(void *)thread_one,NULL);
        pthread_join(tid_one,NULL);
    }
    else
    {
        pthread_create(&tid_two,NULL,(void *)thread_two,NULL);
        pthread_join(tid_two,NULL);
    }
    wait(NULL);
    return 0;
}


2、pid與tid的用途

Linux中,每個進程有一個pid,類型pid_t,由getpid()取得。Linux下的POSIX線程也有一個id,類型pthread_t,由pthread_self()取得,該id由線程維護,其id空間是各個進程獨立的(即不同進程中的線程可能有相同的id)。你可能知道,Linux中的POSIX線程庫實現的線程其實也是一個進程(LWP),只是該進程與主進程(啟動線程的進程)共享一些資源而已,比如代碼段,數據段等。
  有時候我們可能需要知道線程的真實pid。比如進程P1要向另外一個進程P2中的某個線程發送信號時,既不能使用P2的pid,更不能使用線程的pthread id,而只能使用該線程的真實pid,稱為tid。
  有一個函數gettid()可以得到tid,但glibc並沒有實現該函數,只能通過Linux的系統調用syscall來獲取。使用syscall得到tid只需一行代碼,但為了加深各位看官的印象,簡單提供下面場景。
  有一簇進程,其中一個進程中另外啟了一個線程。各進程共享一個數據結構,由shared_ptr指明,其中保存有線程的tid。在各個進程的執行過程中,需要判斷線程是否存在,若不存在則(重新)創建。
  首先,在線程函數的開始,需要將自己的tid保存至共享內存,
點擊(此處)摺疊或打開
  1. #include <sys/syscall.h>
  2. #include <sys/types.h>
  3. void*
  4. thread_func(void *args)
  5. {
  6.     //~ lock shared memory
  7.     shared_ptr->tid = syscall(SYS_gettid); //~ gettid()
  8.     //~ unlock shared memory
  9.     //~ other stuff
  10. }
在各進程中判斷進程是否存在,
點擊(此處)摺疊或打開
  1. //~ lock shared memory
  2. pthread_t id;
  3. if (shared_ptr->tid == 0) { //~ tid is initialized to 0
  4.     pthread_create(&id, NULL, thread_func, NULL);
  5. } else if (shared_ptr->tid > 0) {
  6.     int ret = kill(shared_ptr->tid, 0); //~ send signal 0 to thread
  7.     if (ret != 0) { //~ thread already died
  8.         pthread_create(&id, NULL, thread_func, NULL);
  9.     }
  10. }
  11. //~ unlock shared memory


3、linux 系統中查看pid,tid的方法

  • 樓上說的linux線程和進程是一樣的,這個說法是錯誤的。
  • 看了樓主的問題,感覺樓主是被PID給弄混了,線程進程都會有自己的ID,這個ID就叫做PID,PID是不特指進程ID,線程ID也可以叫做PID。

引用原文
The four threads will have the same PID but only when viewed from above. What you (as a user) call a PID is not what the kernel (looking from below) calls a PID.
In the kernel, each thread has it's own ID, called a PID (although it would possibly make more sense to call this a TID, or thread ID) and they also have a TGID (thread group ID) which is the PID of the thread that started the whole process.
Simplistically, when a new process is created, it appears as a thread where both the PID and TGID are the same (new) number.
When a thread starts another thread, that started thread gets its own PID (so the scheduler can schedule it independently) but it inherits the TGID from the original thread.
That way, the kernel can happily schedule threads independent of what process they belong to, while processes (thread group IDs) are reported to you.
關於線程繼承關係圖如下:
               USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW
在這裡你可以清晰的看到,創建一個新的進程會給一個新的PID和TGID,並且2個值相同,
當創建一個新的線程的時候,會給你一個新的PID,並且TGID和之前開始的進程一致。
  • 樓主按下H,切換到進程視圖,會發現只剩下一個了
建議建議樓主不要被名字PID給迷惑,一個東西在不同視角是不一樣的。
建議樓主用HTOP,清晰方便,高效,還帶命令行顯示圖。
另外附上
Linux通過進程查看線程的方法 1).htop按t(顯示進程線程嵌套關係)和H(顯示線程) ,然後F4過濾進程名。2).ps -eLf | grep java(快照,帶線程命令,e是顯示全部進程,L是顯示線程,f全格式輸出) 3).pstree -p <pid>(顯示進程樹,不加pid顯示所有) 4).top -Hp <pid> (實時) 5).ps -T -p <pid>(快照)推薦程度按數字從小到大。