python發送信號
A. python 多線程與多進程問題
監控一個信號就起一個線程與進程處理。這樣的邏輯是不太合適的。所有的資源都是有限的,如果這樣浪費很快會資源管理失控。
常規的做法是起一個線程池,或者是進程池。 使用線程還是進程取決於你處理的信號的類型。如果計算量大,則需要進程池,如果只是設備等待,比如網路數據收發,則線程也勉強夠用。
信號過來後處理方法有兩種,一種是實時處理,這個沒有好辦法,可以用「微線程」的辦法做,盡量減少處理周期。另外一種是允許少量的延遲。那麼通常的做法是用隊列。將信號放到線程或者是進程池的消息隊列里。然後再由後者分配。
還有一種高效的處理方法,根據信號的值做hash,然後自動分發到不同的CPU或者是伺服器。這個就算是大規模並發處理機制。
通常情況下,比如一個WEB伺服器,它需要獲取一個請求,然後處理響應,可以使用線程模型,或者是進程模型。也是使用典型的池的方法。一個Pool的大於,取決於你的計算 機的計算 能力,內存大小,以及你的並發訪問數量。
所要要啟用多少個呢?假設你的一個信號的處理周期是1秒,你同時有100個信號進來,那麼就需要100個線程或者是進程。
線程數過多,表面上處理能力在增加,不過延遲也在增加,失敗率也會增加。
B. processbuilder 發送信號
processbuilder發送信號需要Root許可權。
kill進程號實現上是發了一個信號給指定的進程。在python里,也可以載入事件處理模塊,處理來自其它程序發過來的信號,可以用KILL工具發信號。
C. 如何使用python處理心音信號
在了解了linux的信號基礎之 後,Python標准庫中的signal包就很容易學習和理解。signal包負責在Python程序內部處理信號,典型的操作包括預設信號處理函數,暫 停並等待信號,以及定時發出SIGALRM等。要注意,signal包主要是針對UNIX平台(比如Linux, MAC OS),而Windows內核中由於對信號機制的支持不充分,所以在Windows上的Python不能發揮信號系統的功能。
信號(signal)-- 進程之間通訊的方式,是一種軟體中斷。一個進程一旦接收到信號就會打斷原來的程序執行流程來處理信號。
定義信號名
signal包定義了各個信號名及其對應的整數,比如:
import signal
print(signal.SIGABRT)
print(signal.SIG_DFL)
Python所用的信號名與Linux一致,可以通過$ man 7 signal 查詢
預設信號處理函數
signal包的核心是使用signal.signal()函數來預設(register)信號處理函數,如下所示:
singnal.signal(signalnum, handler)
signalnum為某個信號,handler為該信號的處理函數。我們在信號基礎里提到,進程可以無視信號,可以採取默認操作,還可以自定義操作。當handler為signal.SIG_IGN時,信號被無視(ignore)。當handler為singal.SIG_DFL,進程採取默認操作(default)。當handler為一個函數名時,進程採取函數中定義的操作。
import signal
# Define signal handler function
def myHandler(signum, frame):
print('I received: ', signum)
# register signal.SIGTSTP's handler
signal.signal(signal.SIGTSTP, myHandler)
signal.pause()
print('End of Signal Demo')
# 有問題待測試
在主程序中,我們首先使用signal.signal()函數來預設信號處理函數。然後我們執行signal.pause()來讓該進程暫停以等待信號, 以等待信號。當信號SIGUSR1被傳遞給該進程時,進程從暫停中恢復,並根據預設,執行SIGTSTP的信號處理函數myHandler()。 myHandler的兩個參數一個用來識別信號(signum),另一個用來獲得信號發生時,進程棧的狀況(stack frame)。這兩個參數都是由signal.singnal()函數來傳遞的。
上面的程序可以保存在一個文件中(比如test.py)。我們使用如下方法運行:
$python test.py
以便讓進程運行。當程序運行到signal.pause()的時候,進程暫停並等待信號。此時,通過按下CTRL+Z向該進程發送SIGTSTP信號。我們可以看到,進程執行了myHandle()函數, 隨後返回主程序,繼續執行。(當然,也可以用$ps查詢process ID, 再使用$kill來發出信號。)
(進程並不一定要使用signal.pause()暫停以等待信號,它也可以在進行工作中接受信號,比如將上面的signal.pause()改為一個需要長時間工作的循環。)
我們可以根據自己的需要更改myHandler()中的操作,以針對不同的信號實現個性化的處理。
定時發出SIGALRM信號
一個有用的函數是signal.alarm(),它被用於在一定時間之後,向進程自身發送SIGALRM信號:
import signal
# Define signal handler function
def myHandler(signum, frame):
print("Now, it's the time")
exit()
# register signal.SIGALRM's handler
signal.signal(signal.SIGALRM, myHandler)
signal.alarm(5)
while True:
print('not yet')
我們這里用了一個無限循環以便讓進程持續運行。在signal.alarm()執行5秒之後,進程將向自己發出SIGALRM信號,隨後,信號處理函數myHandler開始執行。
發送信號
signal包的核心是設置信號處理函數。除了signal.alarm()向自身發送信號之外,並沒有其他發送信號的功能。但在os包中,有類似於linux的kill命令的函數,分別為
os.kill(pid, sid)
os.killpg(pgid, sid)
分別向進程和進程組(見Linux進程關系)發送信號。sid為信號所對應的整數或者singal.SIG*。
實際上signal, pause,kill和alarm都是Linux應用編程中常見的C庫函數,在這里,我們只不過是用Python語言來實現了一下。實際上,Python 的解釋器是使用C語言來編寫的,所以有此相似性也並不意外。此外,在Python 3.4中,signal包被增強,信號阻塞等功能被加入到該包中。我們暫時不深入到該包中。
總結
signal.SIG*
signal.signal()
signal.pause()
signal.alarm()
D. 如何利用python dbus來發送一個信號
dbus用於進程間通信,可以降低不同程序間的耦合性,dbus的原理同分布式計算很象
用python來操作dbus很方便,
一些官方例子: 例子
簡單過程
1.首先要從dbus.service.Object繼承,這樣才可以輸出方法和信號,同時調用dbus.service.Object來初始化bus類型(Session bus or System bus),以及 對象路徑
class Msg(dbus.service.Object):
def __init__(self,bus,object_path):
dbus.service.Object.__init__(self,bus,object_path)
2.輸出信號,先修飾,信號要傳遞的參數有signature確定,然後再定義信號函數,信號函數體本身沒多大意義,有意義的只在於函數體的參數,在dbus中的信號名就是這個信號函數的名字
@dbus.service.signal(dbus_interface=MSG_INTERFACE_URI,
signature='as') #發送了一個可變數組,但數組的類型要一致,這里都是string
def msg_signal(self,msg_list):
print "exported signal: ",msg_list #這個沒有意義
3..定義一個發送信號的函數,注意要返回True,否則如果調用timeout_add的時候,它執行了一次就會停下來,不會重復執行,因為timeout_add碰到False的時候就會停止執行
發送信號,其實也就只是調用剛才修飾的信號函數而已
def construct_msg(self):
timeStamp = time.strftime(TIMEFORMAT)
self.msg_signal(["1111",timeStamp,"This is the content","1 2 3"])
return True
4.連接到bus,注意在連接前要先選好loop的類型,否則不讓連接
DBusGMainLoop(set_as_default=True) #選好loop的類型
bus = dbus.SessionBus()
aMsg = Msg(bus,MSG_OBJ_PATH) #將對象輸出到bus中
gobject.timeout_add(1000,aMsg.construct_msg) #定時發送信號,知道其中的函數返回False為止
loop = gobject.MainLoop()
loop.run()
E. python中子進程發送信號父進程怎麼互發信號
ubuntu下,也就是linux下,通常會用kill -事件編號實現。 你查一下LINUX下的事件就明白了。 kill進程號 實現上是發了一個信號給指定的進程。 在python里,也可以載入事件處理模塊,處理來自其它程序發過來的信號, 當然你可以用KILL工具發信號...
F. python pyqt5 qthread有哪些方法
用例子說明吧,常用的不多
PyQt中的線程類 QtCore.QThread ,使用時繼承QThread類
啟動界面的線程暫稱為UI線程。界面執行命令時都在自己的UI線程中。
如果在UI線程中執行網路連接和資料庫操作等耗時的操作,界面會被卡住,Windows下有可能會出現「無響應」的警告。
阻塞UI線程會降低用戶體驗和應用穩定性。因此我們可以把耗時操作放在線程中去執行。
QThread代表一個線程,我們可以復寫run函數來執行我們要的操作。
QThread可以使用 QtCore.pyqtSignal 來與界面交互和傳輸數據。
PyQt4 QThread 代碼示例
•Python2.7
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore
from PyQt4.QtCore import QCoreApplication
from PyQt4.QtGui import QWidget, QPushButton, QApplication, QTextBrowser
class TimeThread(QtCore.QThread):
signal_time = QtCore.pyqtSignal(str, int) # 信號
def __init__(self, parent=None):
super(TimeThread, self).__init__(parent)
self.working = True
self.num = 0
def start_timer(self):
self.num = 0
self.start()
def run(self):
while self.working:
print "Working", self.thread()
self.signal_time.emit("Running time:", self.num) # 發送信號
self.num += 1
self.sleep(1)
class TimeDialog(QWidget):
def __init__(self):
super(TimeDialog, self).__init__()
self.timer_tv = QTextBrowser(self)
self.init_ui()
self.timer_t = TimeThread()
self.timer_t.signal_time.connect(self.update_timer_tv)
def init_ui(self):
self.resize(300, 200)
self.setWindowTitle('TimeDialog')
self.timer_tv.setText("Wait")
self.timer_tv.setGeometry(QtCore.QRect(10, 145, 198, 26))
self.timer_tv.move(0, 15)
btn1 = QPushButton('Quit', self)
btn1.setToolTip('Click to quit')
btn1.resize(btn1.sizeHint())
btn1.move(200, 150)
btn1.clicked.connect(QCoreApplication.instance().quit)
start_btn = QPushButton('Start', self)
start_btn.setToolTip("Click to start")
start_btn.move(50, 150)
self.connect(start_btn, QtCore.SIGNAL("clicked()"), self.click_start_btn)
def click_start_btn(self):
self.timer_t.start_timer()
def update_timer_tv(self, text, number):
self.timer_tv.setText(self.tr(text + " " + str(number)))
if __name__ == '__main__':
app = QApplication(sys.argv)
time_dialog = TimeDialog()
time_dialog.show()
sys.exit(app.exec_())
QThread中使用的信號 signal_time = QtCore.pyqtSignal(str, int) 指定了參數str和int
發送信號 self.signal_time.emit("Running time:", self.num)
外部接收信號 self.timer_t.signal_time.connect(self.update_timer_tv)
信號連接到方法 update_timer_tv(self, text, number) ,注意信號與方法的參數要一一對應
使用中我們可以定義多種不同的信號 QtCore.pyqtSignal
啟動線程,調用 start()
G. Python 數字信號處理程序實現求解
數字信號處理是把信號用數字或符號表示成序列,通過計算機或通用(專用)信號處理設備,用數值計算方法進行各種處理,達到提取有用信息便於應用的目的。例如:濾波、檢測、變換、增強、估計、識別、參數提取、頻譜分析等。
一般地講,數字信號處理涉及三個步驟:
⑴模數轉換(A/D轉換):把模擬信號變成數字信號,是一個對自變數和幅值同時進行離散化的過程,基本的理論保證是采樣定理。
⑵數字信號處理(DSP):包括變換域分析(如頻域變換)、數字濾波、識別、合成等。
⑶數模轉換(D/A轉換):把經過處理的數字信號還原為模擬信號。通常,這一步並不是必須的。 作為DSP的成功例子有很多,如醫用CT斷層成像掃描儀的發明。它是利用生物體的各個部位對X射線吸收率不同的現象,並利用各個方向掃描的投影數據再構造出檢測體剖面圖的儀器。這種儀器中fft(快速傅里葉變換)起到了快速計算的作用。以後相繼研製出的還有:採用正電子的CT機和基於核磁共振的CT機等儀器,它們為醫學領域作出了很大的貢獻。
信號處理的目的是:削弱信號中的多餘內容;濾出混雜的雜訊和干擾;或者將信號變換成容易處理、傳輸、分析與識別的形式,以便後續的其它處理。 下面的示意圖說明了信號處理的概念。
H. qt與python之間怎麼建立信號槽鏈接
(1)類中信號與槽連接
connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(showOpenFileDlg()));11
(2)類之間槽的連接
//類間信號與槽連接,但是沒有傳遞數據
geometryTransform* geomtry = new geometryTransform();//實例化類的對象
connect(ui->action_Scale, SIGNAL(triggered()), geomtry, SLOT(scale()));123123
//類間信號與槽連接,並且傳遞數據
imageEnhance* imgEnhance = = new imageEnhance();//實例化類的對象
//A->B->A,A 向B發送信號,B執行處理,處理結果再返回A顯示,即操作與顯示分開,更合理
connect(ui->action_MediumFilter, SIGNAL(triggered()), this, SLOT(sendQPixmap()));
connect(this,SIGNAL(getQPixmap(QString)), imgEnhance, SLOT(meanFilter(QString)));
connect(imgEnhance, SIGNAL(getQpixmap(QPixmap*)), this,SLOT(updateView(QPixmap*)))
I. pyqt python 信號簡單問題
self.pushButton_Open_Data.clicked.connect(PF.initialized_Infomation.open_Folder)
J. python 怎麼查看signal
信號(signal)--進程之間通訊的方式,是一種軟體中斷。一個進程一旦接受到信號就會打斷原來的程序執行流程來處理信號。
幾個常用信號:
SIGINT 終止進程 中斷進程 (control+c)
SIGTERM 終止進程 軟體終止信號
SIGKILL 終止進程 殺死進程
SIGALRM 鬧鍾信號
進程結束信號 SIGTERM和SIGKILL的區別
SIGTERM比較友好,進程能捕捉這個信號,根據您的需要來關閉程序。在關閉程序之前,您可以結束打開的記錄文件和完成正在做的任務。在某些情況下,假如進程正在進行作業而且不能中斷,那麼進程可以忽略這個SIGTERM信號。
對於SIGKILL信號,進程是不能忽略的。這是一個 「我不管您在做什麼,立刻停止」的信號。假如您發送SIGKILL信號給進程,Linux就將進程停止在那裡。
發送信號一般有兩種原因:
1(被動式) 內核檢測到一個系統事件.例如子進程退出會像父進程發送SIGCHLD信號.鍵盤按下control+c會發送SIGINT信號
2(主動式) 通過系統調用kill來向指定進程發送信號
補充:
POSIX.1中列出的信號:
信號 值 處理動作 發出信號的原因
----------------------------------------------------------------------
SIGHUP 1 A 終端掛起或者控制進程終止
SIGINT 2 A 鍵盤中斷(如break鍵被按下)
SIGQUIT 3 C 鍵盤的退出鍵被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)發出的退出指令
SIGFPE 8 C 浮點異常
SIGKILL 9 AEF Kill信號
SIGSEGV 11 C 無效的內存引用
SIGPIPE 13 A 管道破裂: 寫一個沒有讀埠的管道
SIGALRM 14 A 由alarm(2)發出的信號
SIGTERM 15 A 終止信號
SIGUSR1 30,10,16 A 用戶自定義信號1
SIGUSR2 31,12,17 A 用戶自定義信號2
SIGCHLD 20,17,18 B 子進程結束信號
SIGCONT 19,18,25 進程繼續(曾被停止的進程)
SIGSTOP 17,19,23 DEF 終止進程
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵
SIGTTIN 21,21,26 D 後台進程企圖從控制終端讀
SIGTTOU 22,22,27 D 後台進程企圖從控制終端寫
處理動作一項中的字母含義如下:
A 預設的動作是終止進程
B 預設的動作是忽略此信號
C 預設的動作是終止進程並進行內核映像轉儲(mp core)
D 預設的動作是停止進程
E 信號不能被捕獲
F 信號不能被忽略
鍵盤和shell的交互:
Ctrl-c Kill foreground process 常用 ;送SIGINT信號,默認進程會結束,但是進程自己可以重定義收到這個信號的行為。
Ctrl-z Suspend foreground process;送SIGSTOP信號,進程只是被停止,再送SIGCONT信號,進程繼續運行。
Ctrl-d Terminate input, or exit shell 常用 有時也會使程序退出,例如沒有參數的cat命令,從終端讀一行顯示一行,知道Ctrl+D終結輸入並終結進程;不是發送信號,而是表示一個特殊的二進制值,表示 EOF。
Ctrl-s Suspend output
Ctrl-q Resume output
Ctrl-o Discard output
Ctrl-l Clear screen
控制字元都是可以用(stty命令)更改的。可以用stty -a看看終端配置。
有些信號不能被屏蔽,比如中斷,還應該有殺死進程的信號,要不然內核怎麼做操作系統中的老大。實際上,SIGKILL和SIGSTOP信號是不能被屏蔽或阻止的,他們的默認動作總是會被執行的