linux中进程pts 1和pts 3,termial创建时ptmx与pts的关系
我們打開(kāi)一個(gè)terminal,那么將會(huì)在devpts文件系統(tǒng)/dev/pts下創(chuàng)建一個(gè)對(duì)應(yīng)的pts字符文件,
該pts字符文件節(jié)點(diǎn)直接由/dev/ptmx節(jié)點(diǎn)的驅(qū)動(dòng)函數(shù)ptmx_open()
調(diào)用devpts_pty_new(tty->link)
[tty對(duì)應(yīng)ptmx,tty->link對(duì)應(yīng)/dev/pts/xxx,那么tty->link->link又對(duì)應(yīng)回ptmx
同樣ptm_driver->other等于pts_driver,pts_driver->other等于ptm_driver]主動(dòng)創(chuàng)建,
而非通過(guò)netlink的udev或者h(yuǎn)otplug配合創(chuàng)建[luther.gliethttp]
1.首先我們打開(kāi)3個(gè)新的terminal終端
使用who am i查詢當(dāng)前終端對(duì)應(yīng)的pts號(hào)
luther@gliethttp:~$ who am i
luther?? pts/3??????? 2009-07-03 09:05 (:0.0)
luther@gliethttp:~$ who am i
luther?? pts/4??????? 2009-07-03 09:08 (:0.0)
luther@gliethttp:~$ who am i
luther?? pts/5??????? 2009-07-03 09:08 (:0.0)
他們分別對(duì)應(yīng)pts 3,4和5.
2.在pts/4終端中執(zhí)行如下命令
luther@gliethttp:~$ cat /dev/pts/3
llllllllls
3.在pts/3終端中輸入平常的命令ls
你會(huì)發(fā)現(xiàn)輸入的數(shù)據(jù)并不能被完全顯示,而2步驟中運(yùn)行的cat? /dev/pts/3
命令確出現(xiàn)了不完整命令,這是怎么回事呢,接下來(lái)我們講一講該現(xiàn)象背后的故事[luther.gliethttp].
luther@gliethttp:~$ l
4.講講現(xiàn)象背后的故事
當(dāng)ubuntu系統(tǒng)創(chuàng)建一個(gè)新的terminal時(shí)(比如上面的pts/3) 4.1 首先執(zhí)行ptm = open('/dev/ptmx',...)操作 4.2 接下來(lái)fork(),然后child將打開(kāi)'/dev/pts/3',dup2到0,1和2句柄上,隨后執(zhí)行execl啟動(dòng)一個(gè)shell. pts = open('/dev/pts/3',...); dup2(pts, 0); // 對(duì)應(yīng)lib庫(kù)中stdin dup2(pts, 1); // 對(duì)應(yīng)lib庫(kù)中stdout dup2(pts, 2); // 對(duì)應(yīng)lib庫(kù)中stderr close(pts); execl("/system/bin/sh", "/system/bin/sh", NULL); // 這樣sh輸入數(shù)據(jù)將全部來(lái)自pts, // sh的輸出數(shù)據(jù)也都全部輸送到pts,也就直接送到了打開(kāi)ptmx的新terminal中. 4.3 新terminal將啟動(dòng)GUI,捕獲按鍵數(shù)據(jù),然后寫(xiě)入ptm,這樣pts將收到數(shù)據(jù),進(jìn)而sh將從stdin中獲得數(shù)據(jù), 于是sh將作進(jìn)一步運(yùn)算,將結(jié)果送給stdout或stderr,進(jìn)而送給pts,于是ptm獲得數(shù)據(jù),然后terminal的GUI 將數(shù)據(jù)顯示出來(lái).
具體流程圖如下[luther.gliethttp]:
terminal捕獲到key按鍵值 ptm pts/3 stdin shell讀到數(shù)據(jù)
shell數(shù)據(jù)結(jié)果 stdout pts/3 ptm terminal顯示
4.4 好了,正常的啟動(dòng)流程圖已經(jīng)有了,來(lái)看看,我們?cè)囼?yàn)時(shí)數(shù)據(jù)出現(xiàn)顯示異常的現(xiàn)象背后到底是怎么發(fā)生的.
與上面正常流程不同的時(shí),我們?cè)诹硗庖粋€(gè)地方執(zhí)行了cat.
這種情況下的流程圖為[luther.gliethttp]:
terminal ptm pts/3 shell
|
運(yùn)行在pts/4上的 cat /dev/pts/3
很明顯terminal發(fā)送數(shù)據(jù)到pts/3之后,
因?yàn)橛?個(gè)獨(dú)立的進(jìn)程都在等待pts/3的數(shù)據(jù),所以他們之間就發(fā)生了對(duì)pts/3數(shù)據(jù)搶奪現(xiàn)象,
因?yàn)閘inux內(nèi)核調(diào)度器根據(jù)當(dāng)時(shí)情況隨時(shí)都會(huì)將他們中的一個(gè)調(diào)出或者調(diào)入,因此數(shù)據(jù)
就出現(xiàn)了一部分被送到了pts/4的cat命令,另一部分被送到了shell,
因?yàn)閟hell具有回顯能力,shell將它接收到的所有字符串一一回顯給terminal,所以terminal顯示
到的數(shù)據(jù)就是shell與cat命令爭(zhēng)搶數(shù)據(jù)時(shí),shell自己搶到的數(shù)據(jù),
而pts/4上顯示的數(shù)據(jù)就是cat命令搶到的數(shù)據(jù)[luther.gliethttp]
比如我們?nèi)匀辉趐ts/4上執(zhí)行cat命令,然后我們?cè)趐ts/5上執(zhí)行echo命令
luther@gliethttp:~$ who am i
luther?? pts/5??????? 2009-07-03 09:08 (:0.0)
luther@gliethttp:~$ echo 'luther.gliethttp' >/dev/pts/3
這時(shí)pts/3對(duì)應(yīng)的terminal將完全顯示'luther.gliethttp'字符串,因?yàn)闆](méi)有人和ptm爭(zhēng)搶數(shù)據(jù)[luther.gliethttp].
4.5 在pts/3自己所在terminal中執(zhí)行cat回是什么現(xiàn)象呢,我么繼續(xù)看看
luther@gliethttp:~$ cat /dev/pts/3
ls
ls
pwd
pwd
可以看到,輸入ls回車之后,顯示了2個(gè)ls,其中1個(gè)ls數(shù)據(jù)是cat命令自己回顯出來(lái)的,
另外一個(gè)ls就來(lái)自/dev/pts/3文件,那這是怎么回事呢,原因是這樣的,
cat和terminal都能獲得鍵盤數(shù)據(jù),cat將鍵盤數(shù)據(jù)直接回顯到terminal上,
而terminal捕獲的數(shù)據(jù)將通過(guò)ptm發(fā)送到pts/3,而cat自己又在等待pts/3的數(shù)據(jù),所以
cat將從pts/3上再次讀取到ptm發(fā)送過(guò)來(lái)的數(shù)據(jù),再一次顯示到terminal上,
那同樣是cat pts/3,為什么就不一樣呢,通過(guò)strace發(fā)現(xiàn),如果在
terminal中直接調(diào)用庫(kù)函數(shù)execve()執(zhí)行另外一個(gè)shell命令,那么sh自身將停止對(duì)stdin進(jìn)行數(shù)據(jù)讀取,
只是等待shell命令退出,數(shù)據(jù)讀取操作權(quán)完全交給被執(zhí)行的shell命令(cat),
所以cat這時(shí)0,1,2都是對(duì)應(yīng)pts/3,因?yàn)閏at /dev/pts/3命令需要打開(kāi)文件,
所以fd = open('/dev/pts/3',...)之后,fd數(shù)值將等于3,這樣cat /dev/pts/3他的
0,1,2和3這4個(gè)句柄都對(duì)應(yīng)pts/3節(jié)點(diǎn)[0為stdin,1為stdout,2為stderr]
所以讀取pts/3的進(jìn)程只有了一個(gè),沒(méi)有人和他爭(zhēng)數(shù)據(jù)了,當(dāng)然cat能夠完全獲得數(shù)據(jù)了,呵呵[luther.gliethttp]
總結(jié)
以上是生活随笔為你收集整理的linux中进程pts 1和pts 3,termial创建时ptmx与pts的关系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: win7 能下node什么版本_微软从未
- 下一篇: linux 内核编译不能打字,linux