欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

初步理解Python進程的信號通訊

 更新時間:2015年04月09日 11:47:27   作者:taiyang1987912  
這篇文章主要介紹了初步理解Python進程的信號通訊,作者列舉了Linux系統(tǒng)下的信號通訊示例,需要的朋友可以參考下

信號的概念

信號(signal)--     進程之間通訊的方式,是一種軟件中斷。一個進程一旦接收到信號就會打斷原來的程序執(zhí)行流程來處理信號。

幾個常用信號:

SIGINT     終止進程  中斷進程  (control+c)

SIGTERM   終止進程     軟件終止信號

SIGKILL   終止進程     殺死進程

SIGALRM 鬧鐘信號
進程結束信號 SIGTERM和SIGKILL的區(qū)別

SIGTERM比較友好,進程能捕捉這個信號,根據您的需要來關閉程序。在關閉程序之前,您可以結束打開的記錄文件和完成正在做的任務。在某些情況下,假如進程正在進行作業(yè)而且不能中斷,那么進程可以忽略這個SIGTERM信號。

對于SIGKILL信號,進程是不能忽略的。這是一個 “我不管您在做什么,立刻停止”的信號。假如您發(fā)送SIGKILL信號給進程,Linux就將進程停止在那里。
發(fā)送信號一般有兩種原因:

1(被動式)  內核檢測到一個系統(tǒng)事件.例如子進程退出會像父進程發(fā)送SIGCHLD信號.鍵盤按下control+c會發(fā)送SIGINT信號

2(主動式)  通過系統(tǒng)調用kill來向指定進程發(fā)送信號
linux操作系統(tǒng)提供的信號

[100003@oss235 myppt]$ kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL

 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE

 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2

13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT

17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU

25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH

29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN

35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4

39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6

59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

Python提供的信號

Python 2.4.3 (#1, Jun 11 2009, 14:09:58)

[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> import signal

>>> dir(signal)

['NSIG', 'SIGABRT', 'SIGALRM', 'SIGBUS', 'SIGCHLD', 'SIGCLD', 'SIGCONT', 'SIGFPE', 'SIGHUP', 'SIGILL', 'SIGINT', 'SIGIO', 'SIGIOT', 'SIGKILL', 'SIGPIPE', 'SIGPOLL', 'SIGPROF', 'SIGPWR', 'SIGQUIT', 'SIGRTMAX', 'SIGRTMIN', 'SIGSEGV', 'SIGSTOP', 'SIGSYS', 'SIGTERM', 'SIGTRAP', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU', 'SIGURG', 'SIGUSR1', 'SIGUSR2', 'SIGVTALRM', 'SIGWINCH', 'SIGXCPU', 'SIGXFSZ', 'SIG_DFL', 'SIG_IGN', '__doc__', '__name__', 'alarm', 'default_int_handler', 'getsignal', 'pause', 'signal']

操作系統(tǒng)規(guī)定了進程收到信號以后的默認行為

但是,我們可以通過綁定信號處理函數來修改進程收到信號以后的行為

有兩個信號是不可更改的SIGTOP和SIGKILL
綁定信號處理函數

  import os  
  import signal  
  from time import sleep  
     
  def onsignal_term(a,b):  
    print '收到SIGTERM信號'  
     
  #這里是綁定信號處理函數,將SIGTERM綁定在函數onsignal_term上面  
  signal.signal(signal.SIGTERM,onsignal_term)  
     
  def onsignal_usr1(a,b):  
    print '收到SIGUSR1信號'  
  #這里是綁定信號處理函數,將SIGUSR1綁定在函數onsignal_term上面  
  signal.signal(signal.SIGUSR1,onsignal_usr1)  
     
  while 1:  
    print '我的進程id是',os.getpid()  
    sleep(10)  

運行該程序。然后通過另外一個進程來發(fā)送信號。
發(fā)送信號

發(fā)送信號的代碼如下:

  import os  
  import signal  
     
  #發(fā)送信號,16175是前面那個綁定信號處理函數的pid,需要自行修改  
  os.kill(16175,signal.SIGTERM)  
  #發(fā)送信號,16175是前面那個綁定信號處理函數的pid,需要自行修改  
  os.kill(16175,signal.SIGUSR1)  

SIGCHLD信號

然后顯示一個子進程結束后自動向父進程發(fā)送SIGCHLD信號的例子。

  ''''''' 
  子進程結束會向父進程發(fā)送SIGCHLD信號 
  '''  
  import os  
  import signal  
  from time import sleep  
     
  def onsigchld(a,b):  
    print '收到子進程結束信號'  
  signal.signal(signal.SIGCHLD,onsigchld)  
     
  pid = os.fork()  
  if pid == 0:  
    print '我是子進程,pid是',os.getpid()  
    sleep(2)  
  else:  
    print '我是父進程,pid是',os.getpid()  
    os.wait() #等待子進程結束  

使用信號需要特別注意的地方:

如果一個進程收到一個SIGUSR1信號,然后執(zhí)行信號綁定函數,第二個SIGUSR2信號又來了,第一個信號沒有被處理完畢的話,第二個信號就會丟棄。

所以,盡量不要在多線程中使用信號。

這個不妥,測試沒發(fā)現(xiàn)有信號丟失

例子演示:

接收信號的程序,你會發(fā)現(xiàn)如果有另外一端使用多線程向這個進程發(fā)送信號,會遺漏一些信號。

  import os  
  import signal  
  from time import sleep  
  import Queue  
     
  QCOUNT = Queue.Queue() #初始化隊列  
     
  def onsigchld(a,b):  
    '''''''收到信號后向隊列中插入一個數字1'''  
    print '收到SIGUSR1信號'  
    sleep(2)  
    QCOUNT.put(1) #向隊列中寫入  
   
  def exithanddle(s,e): 
    raise SystemExit('收到終止命令,退出程序')  
   
  signal.signal(signal.SIGUSR1,onsigchld) #綁定信號處理函數  
  signal.signal(signal.SIGINT,exithanddle) #當按下Ctrl + C 終止進程 
     
  while 1:  
    print '我的pid是',os.getpid()  
    print '現(xiàn)在隊列中元素的個數是',QCOUNT.qsize()  
    sleep(2) 

多線程發(fā)信號端的程序:

 

  ''''''' 
  使用多線程向另外一個進程發(fā)送信號 
  '''  
  import threading  
  import os  
  import signal  
     
  def sendusr1():  
    print '發(fā)送信號'  
    #這里的進程id需要寫前一個程序實際運行的pid  
    os.kill(17788, signal.SIGUSR1)  
      
  WORKER = []  
     
  #開啟6個線程  
  for i in range(1, 7):  
    threadinstance = threading.Thread(target = sendusr1)  
    WORKER.append(threadinstance)  
     
  for i in WORKER:  
    i.start()  
     
  for i in WORKER:  
    i.join()  
     
  print '主線程完成'  

內容補充:

Alarms 是一個特殊信號類型,它可以讓程序要求系統(tǒng)經過一段時間對自己發(fā)送通知。os 標準模塊中指出,它可用于避免無限制阻塞 I/O 操作或其它系統(tǒng)調用。

像下面例子,原本程序睡眠 10 后才打印出 print 'After :', time.ctime(),但是由于 signal.alarm(2),所以 2 秒后就執(zhí)行了打印。

  import signal 
  import time 
   
  def receive_alarm(signum, stack): 
    print 'Alarm :', time.ctime() 
   
  # Call receive_alarm in 2 seconds 
  signal.signal(signal.SIGALRM, receive_alarm) 
  signal.alarm(2) 
   
  print 'Before:', time.ctime() 
  time.sleep(10) 
  print 'After :', time.ctime()  

注意Signal只有主線程才能接收信號,像下面例子,print 'Done waiting' 語句打印不出來,如果不調用 signal.alarm(2) ,程序將永遠阻塞

  import signal 
  import threading 
  import os 
  import time 
   
  def signal_handler(num, stack): 
    print 'Received signal %d in %s' % \ 
      (num, threading.currentThread().name) 
   
  signal.signal(signal.SIGUSR1, signal_handler) 
   
  def wait_for_signal(): 
    print 'Waiting for signal in', threading.currentThread().name 
    signal.pause() 
    print 'Done waiting' 
   
  # Start a thread that will not receive the signal 
  receiver = threading.Thread(target=wait_for_signal, name='receiver') 
  receiver.start() 
  time.sleep(0.1) 
   
  def send_signal(): 
    print 'Sending signal in', threading.currentThread().name 
    os.kill(os.getpid(), signal.SIGUSR1) 
   
  sender = threading.Thread(target=send_signal, name='sender') 
  sender.start() 
  sender.join() 
   
  # Wait for the thread to see the signal (not going to happen!) 
  print 'Waiting for', receiver.name 
  signal.alarm(2) 
  receiver.join() 

還有一點需要注意的是,雖然 alarms 類信號可以在任何線程中調用,但是只能在主線程中接收,像下面例子即使子線程 use_alarm 中調用  signal.alarm(1) ,但是不起作用 :

  import signal 
  import time 
  import threading 
   
  def signal_handler(num, stack): 
    print time.ctime(), 'Alarm in', threading.currentThread().name 
   
  signal.signal(signal.SIGALRM, signal_handler) 
   
  def use_alarm(): 
    t_name = threading.currentThread().name 
    print time.ctime(), 'Setting alarm in', t_name 
    signal.alarm(1) 
    print time.ctime(), 'Sleeping in', t_name 
    time.sleep(3) 
    print time.ctime(), 'Done with sleep in', t_name 
   
  # Start a thread that will not receive the signal 
  alarm_thread = threading.Thread(target=use_alarm, 
                  name='alarm_thread') 
  alarm_thread.start() 
  time.sleep(0.1) 
   
  # Wait for the thread to see the signal (not going to happen!) 
  print time.ctime(), 'Waiting for', alarm_thread.name 
  alarm_thread.join() 
   
  print time.ctime(), 'Exiting normally' 

相關文章

  • Python實現(xiàn)驗證碼識別

    Python實現(xiàn)驗證碼識別

    這篇文章主要介紹了Python實現(xiàn)驗證碼識別的方法,文中講解非常詳細,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-06-06
  • 基于Python實現(xiàn)英語單詞小游戲

    基于Python實現(xiàn)英語單詞小游戲

    這篇文章主要為大家詳細介紹了如何通過Python實現(xiàn)一個簡單的英語單詞小游戲,四級考滿分的學姐告訴你這樣學英語逢考必過,趕緊康康叭
    2022-11-11
  • Python松散正則表達式用法分析

    Python松散正則表達式用法分析

    這篇文章主要介紹了Python松散正則表達式用法,較為詳細的分析了松散正則表達式的概念、功能與相關使用技巧,需要的朋友可以參考下
    2016-04-04
  • Python入門教程(三十一)Python的Try和Except

    Python入門教程(三十一)Python的Try和Except

    這篇文章主要介紹了Python入門教程(三十一)Python的Try Except,當我們調用Python并發(fā)生錯誤或異常時,通常會停止并生成錯誤消息,
    可以使用try語句處理這些異常,需要的朋友可以參考下
    2023-05-05
  • Anaconda中安裝Tensorflow的過程

    Anaconda中安裝Tensorflow的過程

    這篇文章主要介紹了Anaconda中如何安裝Tensorflow,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 使用Python合成圖片的實現(xiàn)代碼(圖片添加個性化文本,圖片上疊加其他圖片)

    使用Python合成圖片的實現(xiàn)代碼(圖片添加個性化文本,圖片上疊加其他圖片)

    這篇文章主要介紹了使用Python合成圖片的實現(xiàn)代碼(圖片添加個性化文本,圖片上疊加其他圖片),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 利用Python破解摩斯密碼

    利用Python破解摩斯密碼

    摩爾斯電碼( 又譯為摩斯密碼,英語:Morse code)是一種時通時斷的信號代碼,通過不同的排列順序來表達不同的英文字母、數字和標點符號。本文將通過Python代碼來實現(xiàn)破解摩斯密碼,感興趣的可以學習一下
    2022-02-02
  • 使用Python腳本對GiteePages進行一鍵部署的使用說明

    使用Python腳本對GiteePages進行一鍵部署的使用說明

    剛好之前有了解過python的自動化,就想著自動化腳本,百度一搜還真有類似的文章。今天就給大家分享下使用Python腳本對GiteePages進行一鍵部署的使用說明,感興趣的朋友一起看看吧
    2021-05-05
  • 對Python 3.2 迭代器的next函數實例講解

    對Python 3.2 迭代器的next函數實例講解

    今天小編就為大家分享一篇對Python 3.2 迭代器的next函數實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Pyqt5自適應布局實例

    Pyqt5自適應布局實例

    今天小編就為大家分享一篇Pyqt5自適應布局實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評論