<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [apue] 使用 Ctrl+S停止輸出而不用掛起前臺進程

      之前一直知道使用 Ctrl+Z 掛起前臺進程來阻止進程運行,之后可以再通過 shell 的作業控制 (jobs / fg N) 來將后臺進程切換為前臺,從而繼續運行。

      最近學到一種新的方法,對于不停有 console 輸出的前臺進程,可以使用 Ctrl+S 來 STOP 一個進程的輸出,從而暫停進程。

      之后可以通過 Ctrl+Q 或輸入任意字符來重啟 (START) 進程輸出,從而繼續運行。

       

      看到這個方法,立即想到寫個腳本驗證一下:

      deadloop.sh

      1 #! /bin/sh
      2 var=1
      3 while :
      4 do
      5   echo this is $var
      6   var=$(($var+1))
      7   usleep 100000
      8 done

       

      這個腳本每 100 毫秒輸出一條日志 “this is N”,其中 N 為日志序號,可以幫我們確定在一次暫停與重啟之間,是否有輸出丟失。

      運行過程中按下 Ctrl+S,輸出果然暫停了:

      >./deadloop.sh 
      this is 1
      this is 2
      this is 3
      this is 4
      

       

       

      再按下 Ctrl+Q 則輸出繼續,直到按下 Ctrl+Z 掛起進程:

      >./deadloop.sh 
      this is 1
      this is 2
      this is 3
      this is 4
      this is 5
      this is 6
      this is 7
      this is 8
      this is 9
      this is 10
      this is 11
      ^Z
      [1]+  Stopped                 ./deadloop.sh
      >
      

       

       

      首先可以看到重啟后的輸出序號與重啟前的可以接上,所以中間并沒有輸出丟失,也就是說是進程被暫停了,而不只是輸出停止了。

      其次在按下 Ctrl+Z 時終端會回顯 ^Z,而按下 Ctrl+S 或 Ctrl+Q 時,終端沒有任何回顯。

       

      于是重點對比按下 Ctrl+S 時與 Ctrl+Z 時進程的狀態,來看這兩種暫停方式的區別。

      通過 ps 命令查看下兩種暫停時進程的狀態:

      Ctrl+S

      >ps xfo pid,ppid,pgid,sid,tpgid,suid,euid,user,stat,tty,command
      PID PPID PGID SID TPGID SUID EUID USER STAT TT COMMAND 6653 6652 2786 2786 -1 500 500 yunhai S ? \_ gnome-pty-helper 6655 6652 6655 6655 6655 500 500 yunhai Ss+ pts/0 \_ /bin/bash 12539 6652 12539 12539 16673 500 500 yunhai Ss pts/1 \_ /bin/bash 16673 12539 16673 12539 16673 500 500 yunhai S+ pts/1 | \_ /bin/sh ./deadloop.sh 12797 6652 12797 12797 13349 500 500 yunhai Ss pts/2 \_ /bin/bash 15959 6652 15959 15959 16766 500 500 yunhai Ss pts/3 \_ /bin/bash 16766 15959 16766 15959 16766 500 500 yunhai R+ pts/3 \_ ps xfo pid,ppid,pgid,sid,tpgid,suid,euid,user,stat,tty,command

        

      Ctrl+Z

      >ps xfo pid,ppid,pgid,sid,tpgid,suid,euid,user,stat,tty,command
        PID  PPID  PGID   SID TPGID  SUID  EUID USER     STAT TT       COMMAND
       6653  6652  2786  2786    -1   500   500 yunhai   S    ?         \_ gnome-pty-helper
       6655  6652  6655  6655  6655   500   500 yunhai   Ss+  pts/0     \_ /bin/bash
      12539  6652 12539 12539 16717   500   500 yunhai   Ss   pts/1     \_ /bin/bash
      16673 12539 16673 12539 16717   500   500 yunhai   T    pts/1     |   \_ /bin/sh ./deadloop.sh
      16688 16673 16673 12539 16717   500   500 yunhai   T    pts/1     |   |   \_ usleep 100000
      16717 12539 16717 12539 16717   500   500 yunhai   R+   pts/1     |   \_ ps xfo pid,ppid,pgid,sid,tpgid,suid,euid,user,stat,tty,command
      12797  6652 12797 12797 13349   500   500 yunhai   Ss   pts/2     \_ /bin/bash
      15959  6652 15959 15959 15959   500   500 yunhai   Ss+  pts/3     \_ /bin/bash
      

       

       

      可以看到最大的不同是,通過 Ctrl+Z 停止的進程狀態為掛起 ('T'),而通過 Ctrl+S 停止的進程狀態為運行 ('S+')。

      另一方面,我們啟動 stap 探測進程間信號的收發,可以在 Ctrl+Z 停止進程時收到以下的輸出:

      stap_signal.sh

      22       events/3         16688 usleep           20     SIGTSTP         
      22       events/3         16673 deadloop.sh      20     SIGTSTP        
      16673    deadloop.sh      12539 bash             17     SIGCHLD        
      16688    usleep           16673 deadloop.sh      17     SIGCHLD 

       

       

      也就是說可以觀察到向前臺進程發送的 SIGTSTP 信號。而在使用 Ctrl+S 時并無特別的信號被偵測到 (僅 usleep 進程結束時向父進程發送的 SIGCHILD)。

       

      注意:此處的 SIGCHLD 并不表示 deadloop.sh 與 usleep 結束,而是掛起時向父進程發送的通知。關于這一點,可以參考我之前寫的一篇文章:

      [apue] 等待子進程的那些事兒

       

      在暫停期間,通過 pstack 命令查看兩種方式暫停的進程堆棧信息:

      Ctrl+S

      >pstack 16673
      #0  0x00119424 in __kernel_vsyscall ()
      #1  0x007a7cd3 in __write_nocancel () from /lib/libc.so.6
      #2  0x007411b4 in _IO_new_file_write () from /lib/libc.so.6
      #3  0x00742a90 in _IO_new_do_write () from /lib/libc.so.6
      #4  0x00741c80 in _IO_new_file_overflow () from /lib/libc.so.6
      #5  0x00744b2a in __overflow () from /lib/libc.so.6
      #6  0x0073e0b5 in putc () from /lib/libc.so.6
      #7  0x080aebb0 in echo_builtin ()
      #8  0x08070c51 in ?? ()
      #9  0x08072e41 in ?? ()
      #10 0x08073aa0 in execute_command_internal ()
      #11 0x080747a4 in execute_command ()
      #12 0x08076d89 in ?? ()
      #13 0x08073a02 in execute_command_internal ()
      #14 0x080747a4 in execute_command ()
      #15 0x08076d89 in ?? ()
      #16 0x08073a02 in execute_command_internal ()
      #17 0x080747a4 in execute_command ()
      #18 0x080750e4 in ?? ()
      #19 0x08073bc4 in execute_command_internal ()
      #20 0x080747a4 in execute_command ()
      #21 0x08060857 in reader_loop ()
      #22 0x0805fed9 in main ()
      

       

       

      Ctrl+Z

      >pstack 16673
      #0  0x00119424 in __kernel_vsyscall ()
      #1  0x00776673 in __waitpid_nocancel () from /lib/libc.so.6
      #2  0x080830f2 in ?? ()
      #3  0x0808432e in wait_for ()
      #4  0x08074635 in execute_command_internal ()
      #5  0x08076dcd in ?? ()
      #6  0x08073a02 in execute_command_internal ()
      #7  0x080747a4 in execute_command ()
      #8  0x080750e4 in ?? ()
      #9  0x08073bc4 in execute_command_internal ()
      #10 0x080747a4 in execute_command ()
      #11 0x08060857 in reader_loop ()
      #12 0x0805fed9 in main ()
      

       

       

      前者停止在了 write 系統調用,后者停止在了 waitpid 系統調用。

      所以前者應該是在輸出時被暫停的,而后者是在等待 usleep 子進程返回時被掛起的。

      大家可以體會一下這兩處方式在細微處的差別。

       

      最后,可以使用 Ctrl+S 停止前臺進程的前提是 必需打開終端的 IXON 標志,使用之前的小工具:

      [apue] 一個查看當前終端標志位設置的小工具

       

      可以查看終端的輸入 flag 是否已經打開了這個標志:

      >./term
      input flag 0x00006f02
          BRKINT
          ICRNL
          IMAXBEL
          IXANY
          IXON
      output flag 0x00000005
          ONLCR
          OPOST
      control flag 0x000004bf
          CREAD
          CSIZE
          CS6
          CS7
          CS8
          HUPCL
      local flag 0x00008a3b
          ECHO
          ECHOE
          ECHOK
          ICANON
          IEXTEN
          ISIG
      

       

       

      一般終端都是打開的。如果再打開 IXANY 標志位,則使用任意鍵都可以重啟被停止的輸出,而不一定要使用 Ctrl+Q。

      最后,還有一個隱藏的前提,就是被暫停的進程在前臺有頻繁的輸出,否則 Ctrl+S 也無用武之地。

      例如,使用下面的命令啟動腳本:

      >./deadloop.sh > deadloop.log
      

       

       

      則無法通過 Ctrl+S 的方法暫停這個進程。 

      總結一下,今天學到一個新的方法去暫停運行中的前臺進程,可能對于運維老鳥來說已經是手到擒來,對我卻是完全的新鮮,

      所以花了些時間研究下,感覺 linux 博大精深,不起眼處可能就藏著一些好東西,值得挖掘!

       

      posted @ 2020-01-25 21:42  goodcitizen  閱讀(894)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 饥渴的熟妇张开腿呻吟视频| 亚洲精品人妻中文字幕| 久久99精品久久久久久| 在线国产精品中文字幕| 视频一区二区三区四区不卡| 国产一区二区日韩在线| 国产成人剧情AV麻豆果冻| 亚洲中文字幕精品一区二区三区| 涩涩爱狼人亚洲一区在线| 国内自拍av在线免费| 強壮公弄得我次次高潮A片| 人妻少妇无码精品视频区| 99在线精品国自产拍中文字幕 | 国产精品看高国产精品不卡| 亚洲精品国产av成人网| 国产真人无码作爱视频免费| 亚洲精品一区国产精品| 亚洲精品成人一二三专区| 在线看片免费不卡人成视频| 99久久成人亚洲精品观看| 日本丰满熟妇videossexhd| 99riav精品免费视频观看| 婷婷四房综合激情五月在线| 大肉大捧一进一出好爽视频mba| 亚洲欧美国产日韩天堂区| 人人人澡人人肉久久精品| 久久久精品94久久精品| 老司机免费的精品视频| 精品无码专区久久久水蜜桃| www国产成人免费观看视频| 九九热久久只有精品2| 亚洲欧美一区二区三区图片| 性做久久久久久久久| 日韩乱码视频一区二区三区| 一二三四中文字幕日韩乱码| 国产自拍偷拍视频在线观看| 无码一区二区三区久久精品| 麻豆国产黄色一级免费片| 国产高清视频在线播放www色| 亚洲AV成人片不卡无码| 精品人妻一区二区三区蜜臀|