pythonnotify
❶ python wait()函數問題
看了你發的函數:
def Wait(self):
self._app.MainLoop()
看名字應該是啟動了阻塞循環,去處理app的請求,這個就是需要一直運行的,因為一旦停止了,你的app請求就沒發處理了。
如果你需要啟動後再執行的別的程序,可以使用多進程,把這個啟動放在別的進程里去執行。
如果解決了您的問題請採納!
如果未解決請繼續追問
❷ 請教,ubuntu10.04下,如何卸載python2.7.8
代碼:
$ ./configure --prefix=/usr/include
$ make
$ sudo checkinstall
然後,python2.7文件夾出現在/usr/include/bin、/usr/include/liclude和/usr/include/lib中,
輸入
代碼:
$ python --version
python 2.6.5
但是,卻出現如下提示:
[text]
$ sudo apt-get autoremove
正在讀取軟體包列表... 完成
正在分析軟體包的依賴關系樹
正在讀取狀態信息... 完成
您也許需要運行「apt-get -f install」來修正上面的錯誤。
下列軟體包有未滿足的依賴關系:
command-not-found: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
computer-janitor: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
computer-janitor-gtk: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
gdebi: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
gdebi-core: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
jockey-common: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
lsb-release: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
nvidia-common: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-appindicator: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-apport: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-apt: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-aptdaemon: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-aptdaemon-gtk: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-brlapi: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-cairo: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-crypto: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-cups: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-dbus: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-egenix-mxdatetime: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-egenix-mxtools: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-farsight: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gconf: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gdbm: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-glade2: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gmenu: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gnome2: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gnomeapplet: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gnomecanvas: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gnomekeyring: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gobject: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gst0.10: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gtk2: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gtksourceview2: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-gtkspell: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-imaging: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-indicate: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-launchpad-integration: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-libxml2: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-newt: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-notify: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-openssl: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-pam: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-pkg-resources: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-problem-report: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-pycurl: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-pygoocanvas: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-pyorbit: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-rdflib: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-setuptools: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-simplejson: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-smbc: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-software-properties: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-twisted-bin: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-twisted-core: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-virtkey: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-vte: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-webkit: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-wnck: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-xapian: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
python-zope.interface: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
screen-resolution-extra: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
software-properties-gtk: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
ufw: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
update-manager: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
update-manager-core: 依賴: python (< 2.7) 但是 2.7.8-1 已經安裝
❸ Python多線程Condition(條件變數)問題
Python下面的消費者、生產者模式可以用生成器協程來實現,要簡單方便的多。
❹ python同時打開幾個程序默認運行哪一個
操作系統的作用
隱藏醜陋復雜的硬體介面,提供良好的抽象介面
管理、調度進程,並且將多個進程對硬體的競爭變得有序
2. 多道技術產生背景
針對單核,實現並發
現在的主機一般是多核,那麼每個核都會利用多道技術
有 4 個 cpu,運行於 cpu1 的某個程序遇到 io 阻塞,會等到 io 結束再重新調度
會被調度到 4 個 cpu 中的任意一個,具體由操作系統調度演算法決定
3. 多道技術空間上的復用:如內存中同時有多道程序
4. 多道技術時間上的復用
復用一個 cpu 的時間片
注意,遇到 io 切,佔用 cpu 時間過長也切
核心在於切之前將進程的狀態保存下來
這樣才能保證下次切換回來時,能基於上次切走的位置繼續運行
進程的概念
進程是一個具有一定獨立功能的程序關於某個數據集合的一次運行活動
進程是操作系統動態執行的基本單元
在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元
進程與程序的區別
程序是指令和數據的有序集合,是一個靜態的概念。程序可以作為一種軟體資料長期存在,是永久的
進程是程序在處理機上的一次執行過程,它是一個動態的概念。進程是有一定生命期的,是暫時的
5. 注意:同一個程序執行兩次,就會在操作系統中出現兩個進程。所以可以同時運行一個軟體,分別做不同的事情也不會混亂,比如可以打開兩個Pycharm做不同的事
6. 進程調度
要想多個進程交替運行,操作系統必須對這些進程進行調度
這個調度也不是隨即進行的,而是需要遵循一定的法則
由此就有了進程的調度演算法:先來先服務調度演算法、短作業優先調度演算法、時間片輪轉法、多級反饋隊列
並行和並發
並行是指在一個時間點上,有多個進程在被 cpu 計算,比如賽跑,兩個人都在不停的往前跑
並發是指資源有限的情況下,在一個時間段上,有多個進程在被 cpu 計算,交替輪流使用資源
並行與並發的區別
並行是從微觀上,也就是在一個精確的時間片刻,有不同的程序在執行,這就要求必須有多個處理器
並發是從宏觀上,在一個時間段上可以看出是同時執行的,比如一個伺服器同時處理多個 session
進程的三狀態
在程序運行的過程中,由於被操作系統的調度演算法控制,程序會進入幾個狀態
就緒
運行
阻塞
2. 舉例說明什麼是 argv,什麼是阻塞
import sys
print(sys.argv)
# 運行結果:
['G:/course_select/進程的概念.py']
# argv 指參數
# sys.argv 是 Python 解釋器在運行的時候傳遞進來的參數
# 首先在cmd輸入以下信息:
python G:/course_select/進程的概念.py
# 列印結果:
['G:/course_select/進程的概念.py']
# 然後在cmd中切換路徑到G盤,接著輸入 python course_select/進程的概念.py
# 列印結果:
['course_select/進程的概念.py']
# 接著,再在cmd中輸入:python course_select/進程的概念.py 123 abc
# 列印結果:
['course_select/進程的概念.py', '123', 'abc']
# 因此,以下程序不能在編輯器里運行,只能在 cmd 裡面使用 Python 運行本文件
# 然後要在後面加上 aaa bbb
# 就像上面的 python course_select/進程的概念.py 123 abc 一樣
if sys.argv[1] == "aaa" and sys.argv[2] == "bbb":
print("登錄成功")
else:
print("登錄失敗")
exit()
print(666)
# 而如果使用input(),其實就是一種阻塞
3. 進程的三狀態圖
.png
同步非同步
同步:形象的說,一件事的執行必須依賴另一件事的結束,強調的是順序性
非同步: 形象的說,兩件事情可以同時進行
注意:同步非同步和並行、並發沒關系
阻塞:等待,比如 input sleep recv accept recvfrom
非阻塞:不等待,start/terminate 都是非阻塞的
阻塞與非阻塞主要是從程序(線程)等待消息通知時的狀態角度來說的
可以分為四類:
同步阻塞
非同步阻塞
同步非阻塞
非同步非阻塞
start/terminate 都是非阻塞的
進程模塊
跟進程相關的基本都在這個模塊里:multiprocessing
父進程與子進程的對比分析
父進程,比如運行本文件
子進程,運行 Process(target=func).start()
父進程與子進程數據隔離
主進程等待子進程結束之後再結束
子進程和主進程之間默認是非同步的
from multiprocessing import Process
import time
def func():
time.sleep(1)
print(666)
if __name__ == "__main__":
# 開啟了一個新的進程,在這個新的進程里執行的 func()
Process(target=func).start()
time.sleep(1)
# 主進程
print(777)
# 777
# 666
# 運行結果仔細觀察發現有非同步的效果
# 也就是說,主進程和新的進程同時執行
3. 上面的示例中為什麼要有 if __name__ == "__main__"?其實這是 windows 操作系統開啟子進程的方式問題
4. 繼續深入
import time
import os
from multiprocessing import Process
def func():
time.sleep(1)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
# 代碼執行到這里並不代表開啟了子進程
p = Process(target=func)
# 開啟了一個子進程,並執行func()
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 主進程運行的結果
777 12340 1636
# 子進程運行的結果
666 7604 12340
# 由上面兩行結果可以得出:
# 利用 os.getpid() 證明兩個進程不一樣
# 另外每次運行,os.getpid() 結果都不一樣
# 但是,12340 是主進程的 id,7604 是子進程的 id
# 1636 是 Pycharm 的 id,排列特點不變
5. 開啟多個相同的子進程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(3)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
for i in range(10):
p = Process(target=func)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 這里需要注意一點:Python 程序一直都是逐行執行
# 但是因為這里設置了時間延遲,因此會先執行主程序的代碼
# 運行結果:
777 29006 3833 # 暫停 2s 後再有下面的結果
666 29007 29006
666 29009 29006
666 29008 29006
666 29010 29006
666 29013 29006
666 29011 29006
666 29012 29006
666 29014 29006
666 29016 29006
666 29015 29006
# 觀察結果發現主進程只運行了一次
# 然後剩下的全是一個子進程重新運行的結果
# 主進程運行完不會結束,它會等子進程全部運行結束
# 注意變數 p 拿到的是最後一個子進程的 id
6. 開啟多個不同的子進程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(2)
print(666, os.getpid(), os.getppid())
def func2():
print(111)
if __name__ == "__main__":
for i in range(3):
p = Process(target=func)
p.start()
for i in range(2):
p = Process(target=func2)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 運行程序時仔細觀察結果顯示順序:
111
111
777 29316 3833
666 29319 29316
666 29317 29316
666 29318 29316
7. 給子進程傳參示例
from multiprocessing import Process
def func(name):
print(666, name)
if __name__ == "__main__":
p = Process(target=func,args=(777,)) # 注意是一個元組
p.start()
import time
from multiprocessing import Process
def func(num, name):
time.sleep(1)
print(num, "hello", name)
if __name__ == "__main__":
for i in range(10):
p = Process(target=func, args=(i, "abc"))
p.start()
print("主進程")
# 運行結果:
666 777
主進程
0 hello abc
2 hello abc
1 hello abc
3 hello abc
5 hello abc
4 hello abc
6 hello abc
7 hello abc
8 hello abc
9 hello abc
# 多運行幾次,發現子進程並不是完全按順序運行的
# 比如上面先出結果 2 hello abc,再出結果 1 hello abc
8. 子進程可以有返回值嗎:不能有返回值,因為子進程函數中的返回值無法傳遞給父進程
import time
from multiprocessing import Process
def func():
time.sleep(3)
print("這是子進程,3s後才運行")
if __name__ == "__main__":
Process(target=func).start()
print("主進程")
# 運行結果:
主進程
這是子進程,3s後才運行
# 主進程會默認等待子進程結束之後才結束
# 因為父進程要負責回收子進程佔用的操作系統資源
相關資源:Python多進程寫入同一文件的方法_python多進程寫入同意文件-其它...
文章知識點與官方知識檔案匹配
Python入門技能樹首頁概覽
194693 人正在系統學習中
點擊閱讀全文
打開CSDN,閱讀體驗更佳
Python多進程(一)進程及進程池_程序員-夏天的博客
print("主進程結束") 通過上述代碼我們發現,multiprocessing.Process幫我們創建一個子進程,並且成功運行,但是我們發現,在子進程還沒執行完的時候主進程就已經死了,那麼這個子進程在主進程結束後就是一個孤兒進程,那麼我們可以讓主進程等待...
Python多進程之Process、Pool、Lock、Queue、Event、Semaphore、Pipe_大 ...
1. Python創建進程類Process python的multiprocessing模塊提供了一個創建進程的類Precess,其創建有以下兩種方法: 創建Process類的實例,並指向目標函數和傳遞參數 自定義一個類並繼承Process類,重寫__init__()和run()方法 ...
python兩個進程同時開啟只運行了一個_二十二、 深入Python的進程和線程(上篇)...
「@Author: Runsen」進程(Process)和線程(Thread)都是操作系統中的基本概念,它們之間有一些優劣和差異,那麼在Python中如何使用進程和線程?CPU計算機的核心是CPU,它承擔了計算機的所有計算任務,CPU就像一個工廠,時刻在運行著,而操作系統管理著計算機,負責任務的調度、資源的分配和管理。進程進程是指在系統中能獨立運行並作為資源分配的基本單位,它是由一組機器指令、數據...
繼續訪問
python啟動多個進程_Python多處理:只有一個進程正在運行
由於注釋表明您希望使用初始化程序和initargs參數傳遞featureVector.在Unix類型的系統上,這將導致大量的性能提升(即使selLabel中只有1個項目),因為該值將使用os.fork基本上免費傳遞給子進程.否則,每次調用foo時,featureVector都將被父進程pickle,通過管道傳遞並由子進程進行unpickled.這將花費很長時間,並且基本上將序列化所有子進程,因為它...
繼續訪問
python多進程多線程,多個程序同時運行_陳逸飛_p的博客_pyth...
python 模塊應用 開發工具 pycharm 實現方法 多任務的實現可以用進程和線程來實現 進程—> 線程---> 多任務應用 多進程操作 比如下載多個文件, 利用cpu 資源 提高效率 多任務: 同一時間執行多個任務, 比如windows操作系統 執行...
python多進程單例_Python多線程處理實例詳解【單進程/多進程】
python — 多線程處理 1、一個進程執行完後,繼續下一個進程 root@72132server:~# cd /root/python/multiprocess/ root@72132server:~/python/multiprocess# ls multprocess.py root@72132server:~/python/multiprocess# cat multprocess...
系統編程__2__父子進程的創建和回收
系統編程 這里寫的是對於小白來說更多的了解系統編程的文章,有寫的不對的地方還懇請各位大佬指出錯誤,小編一定會多多採納[手動多謝]。 那麼,上一次我們稍微了解了一下關於系統編程的一些主要內容[沒有看到的童鞋還請去上一篇文章稍微復習一下噢]。 這節課,我們先來想一想,我們為什麼要學系統編程呢?原因很簡單,我們要充分的利用CPU的性能,CPU和我們人類不太一樣,我們人類大多數情況下,在同一時間,只能完成一件事,而CPU作為無數科學家的心血當然不會這么簡單,CPU能夠同時進行多個進程,這里的進程我們可以理解成任務,
繼續訪問
android 10 system/core無法列印log問題
1.關閉重定向 system/core/init/util.cpp --- a/init/util.cpp +++ b/init/util.cpp @@ -454,7 +454,7 @@ static void InitAborter(const char* abort_message) { // SetStdioToDevNull() must be called again in second stage init. void SetStdioToDevNull(char** argv) { ...
繼續訪問
Python多進程1 一個多進程實例_BBJG_001的博客
下執行,job('主進程step1###')p1=mp.Process(target=job,args=('新進程>>>',))# 創建一個進程# 注意當只有一個參數的時候,一定要在參數後面加一個逗號,因為args需要是一個可以迭代的參量p1.start()# 開始執行新進程# p...
熱門推薦 python多進程多線程,多個程序同時運行
python 多線程 多進程同時運行 多任務要求 python 基礎語法 python 文件目錄操作 python 模塊應用 開發工具 pycharm 實現方法 多任務的實現可以用進程和線程來實現 進程—> 線程----> 多任務應用 多進程操作 比如下載多個文件, 利用cpu 資源 提高效率 多任務: 同一時間執行多個任務, 比如windows操作系統 執行方式有兩種( 表現形式 ) 並發 在單核cpu中: 在一段時間內交替執行多個任務, 例如單核cpu 處理多任務, 操作系統讓各個任務交
繼續訪問
fork()函數
多進程通信 fork()函數
繼續訪問
(1/7)Electron教程(一)什麼是 Electron,由來、適用場景 和 Electron 的環境搭建(1/7)
最近自己有個小的需求,是做一個能編輯本地特定文本的工具,需要跨平台, Windows 和 macOS,這樣,如果用原生開發的話,Windows 就要用c#macOS 就要用swift,學習成本高,並且學完用處也不是很大。我本身是前端開發的,發現了這個electron能滿足我的需求,跨平台運行,內部是 js 驅動的,簡直就是如魚得水。順便把學習的經歷寫出來,分享需要的人,我會按標題序號漸進式地編寫內容。electron。...
繼續訪問
fork()詳解
<一>: fork()函數用來創建新的進程,它的特點是調用一次返回兩次( 在原來的進程中返回新進程的 PID(新進程的 PID 肯定不等於 0), 在新進程中返回為 0.) 函數原型:pid_t fork(void); pid_t getpid(); 獲取當前進程的 pid 值。 pid_t getppid(); 獲取當前進程的父進程 pid 值。 圖一 如圖一所...
繼續訪問
fork()函數詳解
目錄 1.基本了解: 2.fork函數的了解: 3.僵死進程: 1.基本了解: 一個進程,包括代碼、數據和分配給進程的資源。fork 函數會新生成一個進程,調用 fork 函數的進程為父進程,新生成的進程為子進程。在父進程中返回子進程的 pid,在子進程中返回 0,失敗返回-1。 為什麼兩個進程的fpid不同呢,這與fork函數的特性有關。fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值: 1)在父進程中,fork返回新創建子進程的進程...
繼續訪問
Electron在Windows下的環境搭建
Electron作為一種用javascript寫桌面程序的開發方式,現在已經被大眾接受。下面就介紹如何在windows(>win7)下快速搭建Electron開發環境。 1. nodejs 的安裝 從nodejs 下載最新版本的windows安裝程序進行安裝,我下載的是v6.9.1,安裝時一路默認即可,這個安裝會把nodejs和npm配置到系統PATH中,這樣在命令行的任何位置都可以直接...
繼續訪問
python多線程pool_Python mutiprocessing多線程池pool操作示例
本文實例講述了Python mutiprocessing多線程池pool操作。分享給大家供大家參考,具體如下:python — mutiprocessing 多線程 pool腳本代碼:root@72132server:~/python/multiprocess# lsmultiprocess_pool.py multprocess.pyroot@72132server:~/python/multi...
繼續訪問
最新發布 python入門開發學習筆記之守護進程
本節重點 了解守護進程的概念 本節時長需控制在5分鍾內 一 守護進程 主進程創建子進程,然後將該進程設置成守護自己的進程,守護進程就好比崇禎皇帝身邊的老太監,崇禎皇帝已死老太監就跟著殉葬了。 關於守護進程需要強調兩點: 其一:守護進程會在主進程代碼執行結束後就終止 其二:守護進程內無法再開啟子進程,否則拋出異常:AssertionError: daemonic processes are not allowed to have children 如果我們有兩個任務需要並發執行,那麼開一個主進程和一個子進程分
繼續訪問
用python進行多進程編程時,只有主進程可以運行,子進程貌似沒有運行是什麼原因?
找了半天,原來是這個原因!這是因為multiprocessing模塊在交互模式是不支持的,在 cmd 里頭輸入 python xxx.py 來運行起來,你就可以看到子進程的執行了。
繼續訪問
linux中fork() 函數詳解
fork入門知識 一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變數不同,兩個進程也可以做不同的事。 一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都復制到新的新進程中,只有少數值與原來的進程的值不同。相當於克隆了...
繼續訪問
Windows版 Node.js 安裝詳解以及Electron安裝
Windows Node.js 安裝詳解以及Electron安裝詳解,示例版本:node v10.15.0/npm6.4.1 介紹: 簡單的說 Node.js 就是運行在服務端的 JavaScript。 Node.js 是一個基於Chrome JavaScript 運行時建立的一個平台。 Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執...
繼續訪問
Electron 簡介
本教程我們來學習 Electron 的基礎知識,下面我們先來學習一下什麼是 Electron。 Electron是什麼 Electron 是是 GitHub 開發的一個開源框架。它允許使用 Node.js(作為後端)和 Chromium(作為前端)完成桌面 GUI 應用程序的開發。 Electron 可以用於構建具有 HTML、CSS、JavaScript 的跨平台桌面應用程序,它通過將 Chromium 和 node.js 合同一個運行的環境中來實現這一點,應用程序可以打包到 Mac、Windows 和
繼續訪問
Election的優缺點
優點 原生的介面(菜單、消息提醒、系統托盤等)。 上手難度低。能夠使用react、vue等前端框架,能方便地遷移前端組件,構建出漂亮的桌面應用。 方便熱更新 調試和測試方便 Electron使用node.js。因此,您可以導入Chrome應用程序中不容易使用的許多模塊 Electron文檔要好得多,盡管它是一個更年輕的平台 缺點 不適合開發輕量級的應用。即使一個electron的項目框架,也包含chromium內核,打包完接近200G。 相比c++開發的桌面應用,性能遠遠不如後者。 啟動速
繼續訪問
[electron]終極奧義 五千字教程丟給你
前言 本文包含打包、自動更新、簡易API、調試、進程通信等相關知識點,內容較多,可能會引起不適,請酌情查看(手動滑稽)。 electron 簡介 electron是由Github開發,是一個用Html、css、JavaScript來構建桌面應用程序的開源庫,可以打包為Mac、Windows、Linux系統下的應用。 electron是一個運行時環境,包含Node和Chromium,可以理解成把we...
繼續訪問
深入理解Java中的wait() 方法
使用場景 當某個線程獲取到鎖後,發現當前還不滿足執行的條件,就可以調用對象鎖的wait方法,進入等待狀態。 直到某個時刻,外在條件滿足了,就可以由其他線程通過調用notify()或者notifyAll()方法,來喚醒此線程。 這篇文章將側重於討論wait()方法對於線程狀態的影響,以及被喚醒後線程的狀態變更。 條件 只有已經獲取鎖的線程,才可以調用鎖的wait方法,否則會拋出異常IllegalMonitorStateException。 比如下面的代碼,A獲得了鎖後,主動調用wait方法釋放鎖和
繼續訪問
用Electron開發桌面應用的避坑指南(文末送書)
送一波高質量Web開發圖書,送5本書籍,隨你挑。抽獎規則見本文最後!抽獎規則見本文最後!抽獎規則見本文最後!如今,Electron 領域發生了重大的變革,Electron 版本更新換代極快...
繼續訪問
python多進程只有一個進程在執行
python兩個進程同時開啟只運行了一個。
❺ 深入解析Python中的線程同步方法
深入解析Python中的線程同步方法
同步訪問共享資源
在使用線程的時候,一個很重要的問題是要避免多個線程對同一變數或其它資源的訪問沖突。一旦你稍不留神,重疊訪問、在多個線程中修改(共享資源)等這些操作會導致各種各樣的問題;更嚴重的是,這些問題一般只會在比較極端(比如高並發、生產伺服器、甚至在性能更好的硬體設備上)的情況下才會出現。
比如有這樣一個情況:需要追蹤對一事件處理的次數
counter = 0
def process_item(item):
global counter
... do something with item ...
counter += 1
如果你在多個線程中同時調用這個函數,你會發現counter的值不是那麼准確。在大多數情況下它是對的,但有時它會比實際的少幾個。
出現這種情況的原因是,計數增加操作實際上分三步執行:
解釋器獲取counter的當前值計算新值將計算的新值回寫counter變數
考慮一下這種情況:在當前線程獲取到counter值後,另一個線程搶佔到了CPU,然後同樣也獲取到了counter值,並進一步將counter值重新計算並完成回寫;之後時間片重新輪到當前線程(這里僅作標識區分,並非實際當前),此時當前線程獲取到counter值還是原來的,完成後續兩步操作後counter的值實際只加上1。
另一種常見情況是訪問不完整或不一致狀態。這類情況主要發生在一個線程正在初始化或更新數據時,另一個進程卻嘗試讀取正在更改的數據。
原子操作
實現對共享變數或其它資源的同步訪問最簡單的方法是依靠解釋器的原子操作。原子操作是在一步完成執行的操作,在這一步中其它線程無法獲得該共享資源。
通常情況下,這種同步方法只對那些只由單個核心數據類型組成的共享資源有效,譬如,字元串變數、數字、列表或者字典等。下面是幾個線程安全的操作:
讀或者替換一個實例屬性讀或者替換一個全局變數從列表中獲取一項元素原位修改一個列表(例如:使用append增加一個列表項)從字典中獲取一項元素原位修改一個字典(例如:增加一個字典項、調用clear方法)
注意,上面提到過,對一個變數或者屬性進行讀操作,然後修改它,最終將其回寫不是線程安全的。因為另外一個線程會在這個線程讀完卻沒有修改或回寫完成之前更改這個共享變數/屬性。
鎖
鎖是Python的threading模塊提供的最基本的同步機制。在任一時刻,一個鎖對象可能被一個線程獲取,或者不被任何線程獲取。如果一個線程嘗試去獲取一個已經被另一個線程獲取到的鎖對象,那麼這個想要獲取鎖對象的線程只能暫時終止執行直到鎖對象被另一個線程釋放掉。
鎖通常被用來實現對共享資源的同步訪問。為每一個共享資源創建一個Lock對象,當你需要訪問該資源時,調用acquire方法來獲取鎖對象(如果其它線程已經獲得了該鎖,則當前線程需等待其被釋放),待資源訪問完後,再調用release方法釋放鎖:
lock = Lock()
lock.acquire() #: will block if lock is already held
... access shared resource
lock.release()
注意,即使在訪問共享資源的過程中出錯了也應該釋放鎖,可以用try-finally來達到這一目的:
lock.acquire()
try:
... access shared resource
finally:
lock.release() #: release lock, no matter what
在Python 2.5及以後的版本中,你可以使用with語句。在使用鎖的時候,with語句會在進入語句塊之前自動的獲取到該鎖對象,然後在語句塊執行完成後自動釋放掉鎖:
from __future__ import with_statement #: 2.5 only
with lock:
... access shared resource
acquire方法帶一個可選的等待標識,它可用於設定當有其它線程佔有鎖時是否阻塞。如果你將其值設為False,那麼acquire方法將不再阻塞,只是如果該鎖被佔有時它會返回False:
if not lock.acquire(False):
... 鎖資源失敗
else:
try:
... access shared resource
finally:
lock.release()
你可以使用locked方法來檢查一個鎖對象是否已被獲取,注意不能用該方法來判斷調用acquire方法時是否會阻塞,因為在locked方法調用完成到下一條語句(比如acquire)執行之間該鎖有可能被其它線程佔有。
if not lock.locked():
#: 其它線程可能在下一條語句執行之前佔有了該鎖
lock.acquire() #: 可能會阻塞
簡單鎖的缺點
標準的鎖對象並不關心當前是哪個線程佔有了該鎖;如果該鎖已經被佔有了,那麼任何其它嘗試獲取該鎖的線程都會被阻塞,即使是佔有鎖的這個線程。考慮一下下面這個例子:
lock = threading.Lock()
def get_first_part():
lock.acquire()
try:
... 從共享對象中獲取第一部分數據
finally:
lock.release()
return data
def get_second_part():
lock.acquire()
try:
... 從共享對象中獲取第二部分數據
finally:
lock.release()
return data
示例中,我們有一個共享資源,有兩個分別取這個共享資源第一部分和第二部分的函數。兩個訪問函數都使用了鎖來確保在獲取數據時沒有其它線程修改對應的共享數據。
現在,如果我們想添加第三個函數來獲取兩個部分的數據,我們將會陷入泥潭。一個簡單的方法是依次調用這兩個函數,然後返回結合的結果:
def get_both_parts():
first = get_first_part()
seconde = get_second_part()
return first, second
這里的問題是,如有某個線程在兩個函數調用之間修改了共享資源,那麼我們最終會得到不一致的數據。最明顯的解決方法是在這個函數中也使用lock:
def get_both_parts():
lock.acquire()
try:
first = get_first_part()
seconde = get_second_part()
finally:
lock.release()
return first, second
然而,這是不可行的。裡面的兩個訪問函數將會阻塞,因為外層語句已經佔有了該鎖。為了解決這個問題,你可以通過使用標記在訪問函數中讓外層語句釋放鎖,但這樣容易失去控制並導致出錯。幸運的是,threading模塊包含了一個更加實用的鎖實現:re-entrant鎖。
Re-Entrant Locks (RLock)
RLock類是簡單鎖的另一個版本,它的特點在於,同一個鎖對象只有在被其它的線程佔有時嘗試獲取才會發生阻塞;而簡單鎖在同一個線程中同時只能被佔有一次。如果當前線程已經佔有了某個RLock鎖對象,那麼當前線程仍能再次獲取到該RLock鎖對象。
lock = threading.Lock()
lock.acquire()
lock.acquire() #: 這里將會阻塞
lock = threading.RLock()
lock.acquire()
lock.acquire() #: 這里不會發生阻塞
RLock的主要作用是解決嵌套訪問共享資源的問題,就像前面描述的示例。要想解決前面示例中的問題,我們只需要將Lock換為RLock對象,這樣嵌套調用也會OK.
lock = threading.RLock()
def get_first_part():
... see above
def get_second_part():
... see above
def get_both_parts():
... see above
這樣既可以單獨訪問兩部分數據也可以一次訪問兩部分數據而不會被鎖阻塞或者獲得不一致的數據。
注意RLock會追蹤遞歸層級,因此記得在acquire後進行release操作。
Semaphores
信號量是一個更高級的鎖機制。信號量內部有一個計數器而不像鎖對象內部有鎖標識,而且只有當佔用信號量的線程數超過信號量時線程才阻塞。這允許了多個線程可以同時訪問相同的代碼區。
semaphore = threading.BoundedSemaphore()
semaphore.acquire() #: counter減小
... 訪問共享資源
semaphore.release() #: counter增大
當信號量被獲取的時候,計數器減小;當信號量被釋放的時候,計數器增大。當獲取信號量的時候,如果計數器值為0,則該進程將阻塞。當某一信號量被釋放,counter值增加為1時,被阻塞的線程(如果有的話)中會有一個得以繼續運行。
信號量通常被用來限制對容量有限的資源的訪問,比如一個網路連接或者資料庫伺服器。在這類場景中,只需要將計數器初始化為最大值,信號量的實現將為你完成剩下的事情。
max_connections = 10
semaphore = threading.BoundedSemaphore(max_connections)
如果你不傳任何初始化參數,計數器的值會被初始化為1.
Python的threading模塊提供了兩種信號量實現。Semaphore類提供了一個無限大小的信號量,你可以調用release任意次來增大計數器的值。為了避免錯誤出現,最好使用BoundedSemaphore類,這樣當你調用release的次數大於acquire次數時程序會出錯提醒。
線程同步
鎖可以用在線程間的同步上。threading模塊包含了一些用於線程間同步的類。
Events
一個事件是一個簡單的同步對象,事件表示為一個內部標識(internal flag),線程等待這個標識被其它線程設定,或者自己設定、清除這個標識。
event = threading.Event()
#: 一個客戶端線程等待flag被設定
event.wait()
#: 服務端線程設置或者清除flag
event.set()
event.clear()
一旦標識被設定,wait方法就不做任何處理(不會阻塞),當標識被清除時,wait將被阻塞直至其被重新設定。任意數量的線程可能會等待同一個事件。
Conditions
條件是事件對象的高級版本。條件表現為程序中的某種狀態改變,線程可以等待給定條件或者條件發生的信號。
下面是一個簡單的生產者/消費者實例。首先你需要創建一個條件對象:
#: 表示一個資源的附屬項
condition = threading.Condition()
生產者線程在通知消費者線程有新生成資源之前需要獲得條件:
#: 生產者線程
... 生產資源項
condition.acquire()
... 將資源項添加到資源中
condition.notify() #: 發出有可用資源的信號
condition.release()
消費者必須獲取條件(以及相關聯的鎖),然後嘗試從資源中獲取資源項:
#: 消費者線程
condition.acquire()
while True:
...從資源中獲取資源項
if item:
break
condition.wait() #: 休眠,直至有新的資源
condition.release()
... 處理資源
wait方法釋放了鎖,然後將當前線程阻塞,直到有其它線程調用了同一條件對象的notify或者notifyAll方法,然後又重新拿到鎖。如果同時有多個線程在等待,那麼notify方法只會喚醒其中的一個線程,而notifyAll則會喚醒全部線程。
為了避免在wait方法處阻塞,你可以傳入一個超時參數,一個以秒為單位的浮點數。如果設置了超時參數,wait將會在指定時間返回,即使notify沒被調用。一旦使用了超時,你必須檢查資源來確定發生了什麼。
注意,條件對象關聯著一個鎖,你必須在訪問條件之前獲取這個鎖;同樣的,你必須在完成對條件的訪問時釋放這個鎖。在生產代碼中,你應該使用try-finally或者with.
可以通過將鎖對象作為條件構造函數的參數來讓條件關聯一個已經存在的鎖,這可以實現多個條件公用一個資源:
lock = threading.RLock()
condition_1 = threading.Condition(lock)
condition_2 = threading.Condition(lock)
互斥鎖同步
我們先來看一個例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, threading
# 假定這是你的銀行存款:
balance = 0
muxlock = threading.Lock()
def change_it(n):
# 先存後取,結果應該為0:
global balance
balance = balance + n
balance = balance - n
def run_thread(n):
# 循環次數一旦多起來,最後的數字就變成非0
for i in range(100000):
change_it(n)
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t3 = threading.Thread(target=run_thread, args=(9,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print balance
結果 :
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
61
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
24
上面的例子引出了多線程編程的最常見問題:數據共享。當多個線程都修改某一個共享數據的時候,需要進行同步控制。
線程同步能夠保證多個線程安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。互斥鎖為資源引入一個狀態:鎖定/非鎖定。某個線程要更改共享數據時,先將其鎖定,此時資源的狀態為「鎖定」,其他線程不能更改;直到該線程釋放資源,將資源的狀態變成「非鎖定」,其他的線程才能再次鎖定該資源。互斥鎖保證了每次只有一個線程進行寫入操作,從而保證了多線程情況下數據的正確性。
threading模塊中定義了Lock類,可以方便的處理鎖定:
#創建鎖mutex = threading.Lock()
#鎖定mutex.acquire([timeout])
#釋放mutex.release()
其中,鎖定方法acquire可以有一個超時時間的可選參數timeout。如果設定了timeout,則在超時後通過返回值可以判斷是否得到了鎖,從而可以進行一些其他的處理。
使用互斥鎖實現上面的例子的代碼如下:
balance = 0
muxlock = threading.Lock()
def change_it(n):
# 獲取鎖,確保只有一個線程操作這個數
muxlock.acquire()
global balance
balance = balance + n
balance = balance - n
# 釋放鎖,給其他被阻塞的線程繼續操作
muxlock.release()
def run_thread(n):
for i in range(10000):
change_it(n)
加鎖後的結果,就能確保數據正確:
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
❻ python怎麼sendnotifymessage
該函數將指定的消息發送到一個或多個窗口。
此函數為指定的窗口調用窗口程序,直到窗口程序處理完消息再返回。而函數PostMessage不同,將一個消息寄送到一個線程的消息隊列後立即返回。
❼ python生產者消費者問題
這個程序里可能有很多問題。
1.變數傳遞的問題,這個可能會有問題。
2.condition的用法問題。太復雜了。condition.release少加了一個(),這可能是關鍵。
3.isEmpty的判斷問題。
goods建議用Queue,這樣你就省去了condition, 也不用擔心isEmpty的邏輯問題了。
如果你用進程模型,則復雜的多。線程是共享同一個內存空間的。這與GIL沒有關系。
生產消費者模型經常用於任務分發型程序。 比如爬行器,一個線程或者是進程給URL,其它的下載。結果再合並。
或者是WEB SERVER,一個程序accept, 其它的線程進程只是recv, process,send
❽ python多線程老是報錯。大神幫忙看看哈
你好,你具體的代碼我沒看,但單從報錯來看,你的變數名寫錯了:
你定義的是
condition = threading.Condition()
但你第10行引用的是
conditon
少了一個字母i
❾ python多線程怎樣同步
鎖機制
�6�9�6�9threading的Lock類,用該類的acquire函數進行加鎖,用realease函數進行解鎖
import threading
import time
class Num:
def __init__(self):
self.num = 0
self.lock = threading.Lock()
def add(self):
self.lock.acquire()#加鎖,鎖住相應的資源
self.num += 1
num = self.num
self.lock.release()#解鎖,離開該資源
return num
n = Num()
class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item
def run(self):
time.sleep(2)
value = n.add()#將num加1,並輸出原來的數據和+1之後的數據
print(self.item,value)
for item in range(5):
t = jdThread(item)
t.start()
t.join()#使線程一個一個執行
�6�9�6�9當一個線程調用鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。每次只有一個線程可以獲得鎖。如果此時另一個線程試圖獲得這個鎖,該線程就會變為「blocked」狀態,稱為「同步阻塞」(參見多線程的基本概念)。
�6�9�6�9直到擁有鎖的線程調用鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。線程調度程序從處於同步阻塞狀態的線程中選擇一個來獲得鎖,並使得該線程進入運行(running)狀態。
信號量
�6�9�6�9信號量也提供acquire方法和release方法,每當調用acquire方法的時候,如果內部計數器大於0,則將其減1,如果內部計數器等於0,則會阻塞該線程,知道有線程調用了release方法將內部計數器更新到大於1位置。
import threading
import time
class Num:
def __init__(self):
self.num = 0
self.sem = threading.Semaphore(value = 3)
#允許最多三個線程同時訪問資源
def add(self):
self.sem.acquire()#內部計數器減1
self.num += 1
num = self.num
self.sem.release()#內部計數器加1
return num
n = Num()
class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item
def run(self):
time.sleep(2)
value = n.add()
print(self.item,value)
for item in range(100):
t = jdThread(item)
t.start()
t.join()
條件判斷
�6�9�6�9所謂條件變數,即這種機制是在滿足了特定的條件後,線程才可以訪問相關的數據。
�6�9�6�9它使用Condition類來完成,由於它也可以像鎖機制那樣用,所以它也有acquire方法和release方法,而且它還有wait,notify,notifyAll方法。
"""
一個簡單的生產消費者模型,通過條件變數的控制產品數量的增減,調用一次生產者產品就是+1,調用一次消費者產品就會-1.
"""
"""
使用 Condition 類來完成,由於它也可以像鎖機制那樣用,所以它也有 acquire 方法和 release 方法,而且它還有
wait, notify, notifyAll 方法。
"""
import threading
import queue,time,random
class Goods:#產品類
def __init__(self):
self.count = 0
def add(self,num = 1):
self.count += num
def sub(self):
if self.count>=0:
self.count -= 1
def empty(self):
return self.count <= 0
class Procer(threading.Thread):#生產者類
def __init__(self,condition,goods,sleeptime = 1):#sleeptime=1
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime
def run(self):
cond = self.cond
goods = self.goods
while True:
cond.acquire()#鎖住資源
goods.add()
print("產品數量:",goods.count,"生產者線程")
cond.notifyAll()#喚醒所有等待的線程--》其實就是喚醒消費者進程
cond.release()#解鎖資源
time.sleep(self.sleeptime)
class Consumer(threading.Thread):#消費者類
def __init__(self,condition,goods,sleeptime = 2):#sleeptime=2
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime
def run(self):
cond = self.cond
goods = self.goods
while True:
time.sleep(self.sleeptime)
cond.acquire()#鎖住資源
while goods.empty():#如無產品則讓線程等待
cond.wait()
goods.sub()
print("產品數量:",goods.count,"消費者線程")
cond.release()#解鎖資源
g = Goods()
c = threading.Condition()
pro = Procer(c,g)
pro.start()
con = Consumer(c,g)
con.start()
同步隊列
�6�9�6�9put方法和task_done方法,queue有一個未完成任務數量num,put依次num+1,task依次num-1.任務都完成時任務結束。
import threading
import queue
import time
import random
'''
1.創建一個 Queue.Queue() 的實例,然後使用數據對它進行填充。
2.將經過填充數據的實例傳遞給線程類,後者是通過繼承 threading.Thread 的方式創建的。
3.每次從隊列中取出一個項目,並使用該線程中的數據和 run 方法以執行相應的工作。
4.在完成這項工作之後,使用 queue.task_done() 函數向任務已經完成的隊列發送一個信號。
5.對隊列執行 join 操作,實際上意味著等到隊列為空,再退出主程序。
'''
class jdThread(threading.Thread):
def __init__(self,index,queue):
threading.Thread.__init__(self)
self.index = index
self.queue = queue
def run(self):
while True:
time.sleep(1)
item = self.queue.get()
if item is None:
break
print("序號:",self.index,"任務",item,"完成")
self.queue.task_done()#task_done方法使得未完成的任務數量-1
q = queue.Queue(0)
'''
初始化函數接受一個數字來作為該隊列的容量,如果傳遞的是
一個小於等於0的數,那麼默認會認為該隊列的容量是無限的.
'''
for i in range(2):
jdThread(i,q).start()#兩個線程同時完成任務
for i in range(10):
q.put(i)#put方法使得未完成的任務數量+1
❿ Python:進程(threading)
這里是自己寫下關於 Python 跟進程相關的 threading 模塊的一點筆記,跟有些跟 Linux 調用挺像的,有共通之處。
https://docs.python.org/3/library/threading.html?highlight=threading#thread-objects
直接傳入
繼承 Thread 重寫 run 方法
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
group 線程組,未實現
start() 線程就緒
join([timeout]) 阻塞其他線程,直到調用這方法的進程結束或時間到達
RuntimeError: cannot join thread before it is started
get/setName(name) 獲取/設置線程名。
isAlive() 返回線程是否在運行。
is/setDaemon(bool): 獲取/設置是後台線程(默認前台線程(False))。(在start之前設置)
The entire Python program exits when no alive non-daemon threads are left.
沒有非後台進程運行,Python 就退出。
主線程執行完畢後,後台線程不管是成功與否,主線程均停止
t.start()
t.join()
start() 後 join() 會順序執行,失去線程意義
https://docs.python.org/3/library/threading.html?#lock-objects
Lock屬於全局,Rlock屬於線程(R的意思是可重入,線程用Lock的話會死鎖,來看例子)
acquire(blocking=True, timeout=-1) 申請鎖,返回申請的結果
release() 釋放鎖,沒返回結果
https://docs.python.org/3/library/threading.html#condition-objects
可以在構造時傳入rlock lock實例,不然自己生成一個。
acquire([timeout])/release(): 與lock rlock 相同
wait([timeout]): 調用這個方法將使線程進入等待池,並釋放鎖。調用方法前線程必須已獲得鎖定,否則將拋出異常。
notify(): 調用這個方法將從等待池挑選一個線程並通知,收到通知的線程將自動調用acquire()嘗試獲得鎖定(進入鎖定池);其他線程仍然在等待池中。調用這個方法不會釋放鎖定。調用方法前線程必須已獲得鎖定,否則將拋出異常。
notifyAll(): 調用這個方法將通知等待池中所有的線程,這些線程都將進入鎖定池嘗試獲得鎖定。調用這個方法不會釋放鎖定。使用前線程必須已獲得鎖定,否則將拋出異常。
threading.Semaphore(value=1)
https://docs.python.org/3/library/threading.html#semaphore-objects
acquire(blocking=True, timeout=None)
資源數大於0,減一並返回,等於0時等待,blocking為False不阻塞進程
返回值是申請結果
release()
資源數加1
https://docs.python.org/3/library/threading.html#event-objects
事件內置了一個初始為False的標志
is_set() 返回內置標志的狀態
set() 設為True
clear() 設為False
wait(timeout=None) 阻塞線程並等待,為真時返回。返回值只會在等待超時時為False,其他情況為True
https://docs.python.org/3/library/threading.html#timer-objects
threading.Timer(interval, function, args=None, kwargs=None)
第一個參數是時間間隔,單位是秒,整數或者浮點數,負數不會報錯直接執行不等待
可以用cancel() 取消
https://docs.python.org/3/library/threading.html#barrier-objects
threading.Barrier(parties, action=None, timeout=None)
調用的進程數目達到第一個設置的參數就喚醒全部進程
wait(timeout=None)
reset() 重置,等待中的進程收到 BrokenBarrierError 錯誤