導航:首頁 > 編程語言 > python多線程ffmepg

python多線程ffmepg

發布時間:2022-05-11 18:23:23

A. 如何讓python調用多線程來執行機器學習

Python在科學計算領域,有兩個重要的擴展模塊:Numpy和Scipy。其中Numpy是一個用python實現的科學計算包。包括:一個強大的N維數組對象Array;比較成熟的(廣播)函數庫;用於整合C/C++和Fortran代碼的工具包;實用的線性代數、傅里葉變換和隨機數生成函數。SciPy是一個開源的Python演算法庫和數學工具包,SciPy包含的模塊有最優化、線性代數、積分、插值、特殊函數、快速傅里葉變換、信號處理和圖像處理、常微分方程求解和其他科學與工程中常用的計算。其功能與軟體MATLAB、Scilab和GNUOctave類似。Numpy和Scipy常常結合著使用,Python大多數機器學習庫都依賴於這兩個模塊,繪圖和可視化依賴於matplotlib模塊,matplotlib的風格與matlab類似。Python機器學習庫非常多,而且大多數開源,主要有:1.scikit-learnscikit-learn是一個基於SciPy和Numpy的開源機器學習模塊,包括分類、回歸、聚類系列演算法,主要演算法有SVM、邏輯回歸、樸素貝葉斯、Kmeans、DBSCAN等,目前由INRI資助,偶爾Google也資助一點。

B. python多線程有幾種實現方法

基本上有兩種,第一種是繼承Thread類,然後重寫run方法,來實現新線程類的創建。第二種是寫一個類實現Runnable()介面,然後將這個類傳給一個Thread對象來創建線程對象。這兩種方法本質是一樣的。因為Thread類也實現了Runnable介面。

C. Python多線程是什麼意思

簡單地說就是作為可能是僅有的支持多線程的解釋型語言(perl的多線程是殘疾,PHP沒有多線程),Python的多線程是有compromise的,在任意時間只有一個Python解釋器在解釋Python bytecode。
UPDATE:如評論指出,Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的。
如果你的代碼是CPU密集型,多個線程的代碼很有可能是線性執行的。所以這種情況下多線程是雞肋,效率可能還不如單線程因為有context switch
但是:如果你的代碼是IO密集型,多線程可以明顯提高效率。例如製作爬蟲(我就不明白為什麼Python總和爬蟲聯系在一起…不過也只想起來這個例子…),絕大多數時間爬蟲是在等待socket返回數據。這個時候C代碼里是有release GIL的,最終結果是某個線程等待IO的時候其他線程可以繼續執行。
反過來講:你就不應該用Python寫CPU密集型的代碼…效率擺在那裡…
如果確實需要在CPU密集型的代碼里用concurrent,就去用multiprocessing庫。這個庫是基於multi process實現了類multi thread的API介面,並且用pickle部分地實現了變數共享。
再加一條,如果你不知道你的代碼到底算CPU密集型還是IO密集型,教你個方法:
multiprocessing這個mole有一個mmy的sub mole,它是基於multithread實現了multiprocessing的API。
假設你使用的是multiprocessing的Pool,是使用多進程實現了concurrency
from multiprocessing import Pool
如果把這個代碼改成下面這樣,就變成多線程實現concurrency
from multiprocessing.mmy import Pool
兩種方式都跑一下,哪個速度快用哪個就行了。
UPDATE:
剛剛才發現concurrent.futures這個東西,包含ThreadPoolExecutor和ProcessPoolExecutor,可能比multiprocessing更簡單

D. 為什麼有人說 Python 的多線程是雞肋呢

首先,我並不認同這個觀點,我覺得覺得Python 的多線程是雞肋多餘的人,應該還沒有完全使用過Python 的多線程功能,並沒有發掘它的潛在能力。

Python多線程最大的優點就是使用方便,很多時候我們並不需要做大量的密集型數據的處理運算,這時候用Python多線程是最方便快捷的,可以大大減少工作量、提高工作效率。

從以上幾點我們就可以看出,Python多線程並不雞肋,只是有時候使用者在不巧當的地方使用,它自然不是那麼順手,我們加深熟悉了解Python多線程的適用范圍。

E. python多線程的幾種方法

Python進階(二十六)-多線程實現同步的四種方式
臨界資源即那些一次只能被一個線程訪問的資源,典型例子就是列印機,它一次只能被一個程序用來執行列印功能,因為不能多個線程同時操作,而訪問這部分資源的代碼通常稱之為臨界區。
鎖機制
threading的Lock類,用該類的acquire函數進行加鎖,用realease函數進行解鎖
import threadingimport timeclass 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()#使線程一個一個執行

當一個線程調用鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。每次只有一個線程可以獲得鎖。如果此時另一個線程試圖獲得這個鎖,該線程就會變為「blocked」狀態,稱為「同步阻塞」(參見多線程的基本概念)。
直到擁有鎖的線程調用鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。線程調度程序從處於同步阻塞狀態的線程中選擇一個來獲得鎖,並使得該線程進入運行(running)狀態。
信號量
信號量也提供acquire方法和release方法,每當調用acquire方法的時候,如果內部計數器大於0,則將其減1,如果內部計數器等於0,則會阻塞該線程,知道有線程調用了release方法將內部計數器更新到大於1位置。
import threadingimport timeclass 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):

F. python怎麼執行ffmpeg

在ubuntu環境下,在python程序中調用ffmpeg的一條命令:
ffmpeg -i yourVideo.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90-f image2 thumbnails-%02d.jpeg

G. python多線程對多核的利用

GIL 與 Python 線程的糾葛
GIL 是什麼東西?它對我們的 python 程序會產生什麼樣的影響?我們先來看一個問題。運行下面這段 python 程序,CPU 佔用率是多少?
# 請勿在工作中模仿,危險:)
def dead_loop():
while True:
pass

dead_loop()

答案是什麼呢,佔用 100% CPU?那是單核!還得是沒有超線程的古董 CPU。在我的雙核 CPU 上,這個死循環只會吃掉我一個核的工作負荷,也就是只佔用 50% CPU。那如何能讓它在雙核機器上佔用 100% 的 CPU 呢?答案很容易想到,用兩個線程就行了,線程不正是並發分享 CPU 運算資源的嗎。可惜答案雖然對了,但做起來可沒那麼簡單。下面的程序在主線程之外又起了一個死循環的線程
import threading

def dead_loop():
while True:
pass

# 新起一個死循環線程
t = threading.Thread(target=dead_loop)
t.start()

# 主線程也進入死循環
dead_loop()

t.join()

按道理它應該能做到佔用兩個核的 CPU 資源,可是實際運行情況卻是沒有什麼改變,還是只佔了 50% CPU 不到。這又是為什麼呢?難道 python 線程不是操作系統的原生線程?打開 system monitor 一探究竟,這個佔了 50% 的 python 進程確實是有兩個線程在跑。那這兩個死循環的線程為何不能占滿雙核 CPU 資源呢?其實幕後的黑手就是 GIL。
GIL 的迷思:痛並快樂著
GIL 的全稱為 Global Interpreter Lock ,意即全局解釋器鎖。在 Python 語言的主流實現 CPython 中,GIL 是一個貨真價實的全局線程鎖,在解釋器解釋執行任何 Python 代碼時,都需要先獲得這把鎖才行,在遇到 I/O 操作時會釋放這把鎖。如果是純計算的程序,沒有 I/O 操作,解釋器會每隔 100 次操作就釋放這把鎖,讓別的線程有機會執行(這個次數可以通過sys.setcheckinterval 來調整)。所以雖然 CPython 的線程庫直接封裝操作系統的原生線程,但 CPython 進程做為一個整體,同一時間只會有一個獲得了 GIL 的線程在跑,其它的線程都處於等待狀態等著 GIL 的釋放。這也就解釋了我們上面的實驗結果:雖然有兩個死循環的線程,而且有兩個物理 CPU 內核,但因為 GIL 的限制,兩個線程只是做著分時切換,總的 CPU 佔用率還略低於 50%。
看起來 python 很不給力啊。GIL 直接導致 CPython 不能利用物理多核的性能加速運算。那為什麼會有這樣的設計呢?我猜想應該還是歷史遺留問題。多核 CPU 在 1990 年代還屬於類科幻,Guido van Rossum 在創造 python 的時候,也想不到他的語言有一天會被用到很可能 1000+ 個核的 CPU 上面,一個全局鎖搞定多線程安全在那個時代應該是最簡單經濟的設計了。簡單而又能滿足需求,那就是合適的設計(對設計來說,應該只有合適與否,而沒有好與不好)。怪只怪硬體的發展實在太快了,摩爾定律給軟體業的紅利這么快就要到頭了。短短 20 年不到,代碼工人就不能指望僅僅靠升級 CPU 就能讓老軟體跑的更快了。在多核時代,編程的免費午餐沒有了。如果程序不能用並發擠干每個核的運算性能,那就意謂著會被淘汰。對軟體如此,對語言也是一樣。那 Python 的對策呢?
Python 的應對很簡單,以不變應萬變。在最新的 python 3 中依然有 GIL。之所以不去掉,原因嘛,不外以下幾點:
欲練神功,揮刀自宮:
CPython 的 GIL 本意是用來保護所有全局的解釋器和環境狀態變數的。如果去掉 GIL,就需要多個更細粒度的鎖對解釋器的眾多全局狀態進行保護。或者採用 Lock-Free 演算法。無論哪一種,要做到多線程安全都會比單使用 GIL 一個鎖要難的多。而且改動的對象還是有 20 年歷史的 CPython 代碼樹,更不論有這么多第三方的擴展也在依賴 GIL。對 Python 社區來說,這不異於揮刀自宮,重新來過。
就算自宮,也未必成功:
有位牛人曾經做了一個驗證用的 CPython,將 GIL 去掉,加入了更多的細粒度鎖。但是經過實際的測試,對單線程程序來說,這個版本有很大的性能下降,只有在利用的物理 CPU 超過一定數目後,才會比 GIL 版本的性能好。這也難怪。單線程本來就不需要什麼鎖。單就鎖管理本身來說,鎖 GIL 這個粗粒度的鎖肯定比管理眾多細粒度的鎖要快的多。而現在絕大部分的 python 程序都是單線程的。再者,從需求來說,使用 python 絕不是因為看中它的運算性能。就算能利用多核,它的性能也不可能和 C/C++ 比肩。費了大力氣把 GIL 拿掉,反而讓大部分的程序都變慢了,這不是南轅北轍嗎。
難道 Python 這么優秀的語言真的僅僅因為改動困難和意義不大就放棄多核時代了嗎?其實,不做改動最最重要的原因還在於:不用自宮,也一樣能成功!
其它神功
那除了切掉 GIL 外,果然還有方法讓 Python 在多核時代活的滋潤?讓我們回到本文最初的那個問題:如何能讓這個死循環的 Python 腳本在雙核機器上佔用 100% 的 CPU?其實最簡單的答案應該是:運行兩個 python 死循環的程序!也就是說,用兩個分別占滿一個 CPU 內核的 python 進程來做到。確實,多進程也是利用多個 CPU 的好方法。只是進程間內存地址空間獨立,互相協同通信要比多線程麻煩很多。有感於此,Python 在 2.6 里新引入了 multiprocessing這個多進程標准庫,讓多進程的 python 程序編寫簡化到類似多線程的程度,大大減輕了 GIL 帶來的不能利用多核的尷尬。
這還只是一個方法,如果不想用多進程這樣重量級的解決方案,還有個更徹底的方案,放棄 Python,改用 C/C++。當然,你也不用做的這么絕,只需要把關鍵部分用 C/C++ 寫成 Python 擴展,其它部分還是用 Python 來寫,讓 Python 的歸 Python,C 的歸 C。一般計算密集性的程序都會用 C 代碼編寫並通過擴展的方式集成到 Python 腳本里(如 NumPy 模塊)。在擴展里就完全可以用 C 創建原生線程,而且不用鎖 GIL,充分利用 CPU 的計算資源了。不過,寫 Python 擴展總是讓人覺得很復雜。好在 Python 還有另一種與 C 模塊進行互通的機制 : ctypes
利用 ctypes 繞過 GIL
ctypes 與 Python 擴展不同,它可以讓 Python 直接調用任意的 C 動態庫的導出函數。你所要做的只是用 ctypes 寫些 python 代碼即可。最酷的是,ctypes 會在調用 C 函數前釋放 GIL。所以,我們可以通過 ctypes 和 C 動態庫來讓 python 充分利用物理內核的計算能力。讓我們來實際驗證一下,這次我們用 C 寫一個死循環函數
extern"C"
{
void DeadLoop()
{
while (true);
}
}

用上面的 C 代碼編譯生成動態庫 libdead_loop.so (Windows 上是 dead_loop.dll)
,接著就要利用 ctypes 來在 python 里 load 這個動態庫,分別在主線程和新建線程里調用其中的 DeadLoop
from ctypes import *
from threading import Thread

lib = cdll.LoadLibrary("libdead_loop.so")
t = Thread(target=lib.DeadLoop)
t.start()

lib.DeadLoop()

這回再看看 system monitor,Python 解釋器進程有兩個線程在跑,而且雙核 CPU 全被占滿了,ctypes 確實很給力!需要提醒的是,GIL 是被 ctypes 在調用 C 函數前釋放的。但是 Python 解釋器還是會在執行任意一段 Python 代碼時鎖 GIL 的。如果你使用 Python 的代碼做為 C 函數的 callback,那麼只要 Python 的 callback 方法被執行時,GIL 還是會跳出來的。比如下面的例子:
extern"C"
{
typedef void Callback();
void Call(Callback* callback)
{
callback();
}
}

from ctypes import *
from threading import Thread

def dead_loop():
while True:
pass

lib = cdll.LoadLibrary("libcall.so")
Callback = CFUNCTYPE(None)
callback = Callback(dead_loop)

t = Thread(target=lib.Call, args=(callback,))
t.start()

lib.Call(callback)

注意這里與上個例子的不同之處,這次的死循環是發生在 Python 代碼里 (DeadLoop 函數) 而 C 代碼只是負責去調用這個 callback 而已。運行這個例子,你會發現 CPU 佔用率還是只有 50% 不到。GIL 又起作用了。
其實,從上面的例子,我們還能看出 ctypes 的一個應用,那就是用 Python 寫自動化測試用例,通過 ctypes 直接調用 C 模塊的介面來對這個模塊進行黑盒測試,哪怕是有關該模塊 C 介面的多線程安全方面的測試,ctypes 也一樣能做到。
結語
雖然 CPython 的線程庫封裝了操作系統的原生線程,但卻因為 GIL 的存在導致多線程不能利用多個 CPU 內核的計算能力。好在現在 Python 有了易經筋(multiprocessing), 吸星大法(C 語言擴展機制)和獨孤九劍(ctypes),足以應付多核時代的挑戰,GIL 切還是不切已經不重要了,不是嗎。

H. python 多線程怎麼同時一直運行

科技在發展,時代在進步,我們的CPU也越來越快,CPU抱怨,P大點事兒佔了我一定的時間,其實我同時干多個活都沒問題的;於是,操作系

統就進入了多任務時代。我們聽著音樂吃著火鍋的不在是夢想。

python提供了兩個模塊來實現多線程thread 和threading ,thread 有一些缺點,在threading 得到了彌補,為了不浪費你和時間,所以我們直

接學習threading 就可以了。

I. python 多進程和多線程配合

由於python的多線程中存在PIL鎖,因此python的多線程不能利用多核,那麼,由於現在的計算機是多核的,就不能充分利用計算機的多核資源。但是python中的多進程是可以跑在不同的cpu上的。因此,嘗試了多進程+多線程的方式,來做一個任務。比如:從中科大的鏡像源中下載多個rpm包。
#!/usr/bin/pythonimport reimport commandsimport timeimport multiprocessingimport threadingdef download_image(url):
print '*****the %s rpm begin to download *******' % url
commands.getoutput('wget %s' % url)def get_rpm_url_list(url):
commands.getoutput('wget %s' % url)
rpm_info_str = open('index.html').read()

regu_mate = '(?<=<a href=")(.*?)(?=">)'
rpm_list = re.findall(regu_mate, rpm_info_str)

rpm_url_list = [url + rpm_name for rpm_name in rpm_list] print 'the count of rpm list is: ', len(rpm_url_list) return rpm_url_
def multi_thread(rpm_url_list):
threads = [] # url = 'https://mirrors.ustc.e.cn/centos/7/os/x86_64/Packages/'
# rpm_url_list = get_rpm_url_list(url)
for index in range(len(rpm_url_list)): print 'rpm_url is:', rpm_url_list[index]
one_thread = threading.Thread(target=download_image, args=(rpm_url_list[index],))
threads.append(one_thread)

thread_num = 5 # set threading pool, you have put 4 threads in it
while 1:
count = min(thread_num, len(threads)) print '**********count*********', count ###25,25,...6707%25

res = [] for index in range(count):
x = threads.pop()
res.append(x) for thread_index in res:
thread_index.start() for j in res:
j.join() if not threads:
def multi_process(rpm_url_list):
# process num at the same time is 4
process = []
rpm_url_group_0 = []
rpm_url_group_1 = []
rpm_url_group_2 = []
rpm_url_group_3 = [] for index in range(len(rpm_url_list)): if index % 4 == 0:
rpm_url_group_0.append(rpm_url_list[index]) elif index % 4 == 1:
rpm_url_group_1.append(rpm_url_list[index]) elif index % 4 == 2:
rpm_url_group_2.append(rpm_url_list[index]) elif index % 4 == 3:
rpm_url_group_3.append(rpm_url_list[index])
rpm_url_groups = [rpm_url_group_0, rpm_url_group_1, rpm_url_group_2, rpm_url_group_3] for each_rpm_group in rpm_url_groups:
each_process = multiprocessing.Process(target = multi_thread, args = (each_rpm_group,))
process.append(each_process) for one_process in process:
one_process.start() for one_process in process:
one_process.join()# for each_url in rpm_url_list:# print '*****the %s rpm begin to download *******' %each_url## commands.getoutput('wget %s' %each_url)
def main():
url = 'https://mirrors.ustc.e.cn/centos/7/os/x86_64/Packages/'
url_paas = 'http://mirrors.ustc.e.cn/centos/7.3.1611/paas/x86_64/openshift-origin/'
url_paas2 ='http://mirrors.ustc.e.cn/fedora/development/26/Server/x86_64/os/Packages/u/'

start_time = time.time()
rpm_list = get_rpm_url_list(url_paas) print multi_process(rpm_list) # print multi_thread(rpm_list)
#print multi_process()
# print multi_thread(rpm_list)
# for index in range(len(rpm_list)):
# print 'rpm_url is:', rpm_list[index]
end_time = time.time() print 'the download time is:', end_time - start_timeprint main()123456789101112131415161718

代碼的功能主要是這樣的:
main()方法中調用get_rpm_url_list(base_url)方法,獲取要下載的每個rpm包的具體的url地址。其中base_url即中科大基礎的鏡像源的地址,比如:http://mirrors.ustc.e.cn/centos/7.3.1611/paas/x86_64/openshift-origin/,這個地址下有幾十個rpm包,get_rpm_url_list方法將每個rpm包的url地址拼出來並返回。
multi_process(rpm_url_list)啟動多進程方法,在該方法中,會調用多線程方法。該方法啟動4個多進程,將上面方法得到的rpm包的url地址進行分組,分成4組,然後每一個組中的rpm包再最後由不同的線程去執行。從而達到了多進程+多線程的配合使用。
代碼還有需要改進的地方,比如多進程啟動的進程個數和rpm包的url地址分組是硬編碼,這個還需要改進,畢竟,不同的機器,適合同時啟動的進程個數是不同的。

閱讀全文

與python多線程ffmepg相關的資料

熱點內容
管家婆輝煌2加密狗挪到另一台電腦 瀏覽:760
摩托車在哪裡app看考題 瀏覽:356
蘋果5app在哪裡設置 瀏覽:737
如何查看伺服器的磁碟使用 瀏覽:165
python蒙特卡洛模型投點圖 瀏覽:330
安卓手機屬於什麼介面 瀏覽:742
微信群推廣網站源碼 瀏覽:764
九江離鷹潭源碼 瀏覽:719
python可以當作函數的返回值 瀏覽:422
地鐵逃生體驗服怎麼進入安卓 瀏覽:833
齊魯工惠app的中獎記錄在哪裡 瀏覽:759
linuxkill命令詳解 瀏覽:103
dhcp伺服器動態分配地址 瀏覽:265
門禁卡加密了能破解嗎 瀏覽:215
在哪裡下載百度網盤app 瀏覽:917
伺服器要升級什麼意思 瀏覽:831
銀行還房貸解壓方法 瀏覽:702
伺服器主機辦公如何提速 瀏覽:920
cad列印為pdf 瀏覽:418
賣手錶的app哪裡可以賣 瀏覽:55