當前位置:首頁 » 編程語言 » pythongetoutput

pythongetoutput

發布時間: 2023-08-07 01:21:07

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 commands 需要導入 哪個模塊

要獲得shell命令的輸出只需要`cmd`就可以了,
需要得到命令執行的狀態則需要判斷$?的值, 在Python中有一個模塊commands也很容易做到以上的效果.

看一下三個函數:

1). commands.getstatusoutput(cmd)

用os.popen()執行命令cmd, 然後返回兩個元素的元組(status, result). cmd執行的方式是{ cmd ; } 2>&1, 這樣返回結果裡面就會包含標准輸出和標准錯誤.

2). commands.getoutput(cmd)

只返回執行的結果, 忽略返回值.

3). commands.getstatus(file)

返回ls -ld file執行的結果.

看一下這些函數使用的例子:
>>> import commands
>>> commands.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> commands.getstatusoutput('cat /bin/junk')
(256, 'cat: /bin/junk: No such file or directory')
>>> commands.getstatusoutput('/bin/junk')
(256, 'sh: /bin/junk: not found')
>>> commands.getoutput('ls /bin/ls')
'/bin/ls'
>>> commands.getstatus('/bin/ls')
'-rwxr-xr-x 1 root 13352 Oct 14 1994 /bin/ls'

③ 怎麼在python腳本裡面調用另外一個帶參數的腳本

一般情況下都是通過import腳本,然後直接調用腳本里的函數,調用函數就可以直接傳遞參數;因為Python並不像C語言那樣有main函數。

importB(腳本名稱)
B.hello(參數A,參數B)

④ python 中os.system和commands.getoutput的區別

1. 使用os.system("cmd")

這是最簡單的一種方法,特點是執行的時候程序會打出cmd在linux上執行的信息。使用前需要import os。

[python]

os.system("ls")

2. 使用Popen模塊產生新的process

現在大部分人都喜歡使用Popen。Popen方法不會列印出cmd在linux上執
行的信息。的確,Popen非常強大,支持多種參數和模式。使用前需要from subprocess import Popen,
PIPE。但是Popen函數有一個缺陷,就是它是一個阻塞的方法。如果運行cmd時產生的內容非常多,函數非常容易阻塞住。解決辦法是不使用
wait()方法,但是也不能獲得執行的返回值了。

Popen原型是:

[python]

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

參數bufsize:指定緩沖。我到現在還不清楚這個參數的具體含義,望各個大牛指點。

參數executable用於指定可執行程序。一般情況下我們通過args參數來設置所要運行的程序。如果將參數shell設為 True,executable將指定程序使用的shell。在windows平台下,默認的shell由COMSPEC環境變數來指定。

參數stdin, stdout, stderr分別表示程序的標准輸入、輸出、錯誤句柄。他們可以是PIPE,文件描述符或文件對象,也可以設置為None,表示從父進程繼承。

參數preexec_fn只在Unix平台下有效,用於指定一個可執行對象(callable object),它將在子進程運行之前被調用。

參數Close_sfs:在windows平台
下,如果close_fds被設置為True,則新創建的子進程將不會繼承父進程的輸入、輸出、錯誤管
道。我們不能將close_fds設置為True同時重定向子進程的標准輸入、輸出與錯誤(stdin, stdout, stderr)。

如果參數shell設為true,程序將通過shell來執行。

參數cwd用於設置子進程的當前目錄。

參數env是字典類型,用於指定子進程的環境變數。如果env = None,子進程的環境變數將從父進程中繼承。

參數Universal_newlines:不同操作系統下,文本的換行符是不一樣的。如:windows下用』/r/n』表示換,而Linux下用 『/n』。如果將此參數設置為True,Python統一把這些換行符當作』/n』來處理。

參數startupinfo與createionflags只在windows下用效,它們將被傳遞給底層的CreateProcess()函數,用 於設置子進程的一些屬性,如:主窗口的外觀,進程的優先順序等等。

subprocess.PIPE
在創建Popen對象時,subprocess.PIPE可以初始化stdin, stdout或stderr參數,表示與子進程通信的標准流。

subprocess.STDOUT
創建Popen對象時,用於初始化stderr參數,表示將錯誤通過標准輸出流輸出。

Popen的方法:

Popen.poll()
用於檢查子進程是否已經結束。設置並返回returncode屬性。

Popen.wait()
等待子進程結束。設置並返回returncode屬性。

Popen.communicate(input=None)
與子進程進行交互。向stdin發送數據,或從stdout和stderr中讀取數據。可選參數input指定發送到子進程的參數。
Communicate()返回一個元組:(stdoutdata,
stderrdata)。注意:如果希望通過進程的stdin向其發送數據,在創建Popen對象的時候,參數stdin必須被設置為PIPE。同樣,如
果希望從stdout和stderr獲取數據,必須將stdout和stderr設置為PIPE。

Popen.send_signal(signal)
向子進程發送信號。

Popen.terminate()
停止(stop)子進程。在windows平台下,該方法將調用Windows API TerminateProcess()來結束子進程。

Popen.kill()
殺死子進程。

Popen.stdin
如果在創建Popen對象是,參數stdin被設置為PIPE,Popen.stdin將返回一個文件對象用於策子進程發送指令。否則返回None。

Popen.stdout
如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。否則返回 None。

Popen.stderr
如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。否則返回 None。

Popen.pid
獲取子進程的進程ID。

Popen.returncode
獲取進程的返回值。如果進程還沒有結束,返回None。

例如:

[python]

p = Popen("cp -rf a/* b/", shell=True, stdout=PIPE, stderr=PIPE)
p.wait()
if p.returncode != 0:
print "Error."
return -1

3. 使用commands.getstatusoutput方法
這個方法也不會列印出cmd在linux上執行的信息。這個方法唯一的優點是,它不是一個阻塞的方法。即沒有Popen函數阻塞的問題。使用前需要import commands。

例如:

[python]

status, output = commands.getstatusoutput("ls")

還有隻獲得output和status的方法:

[python]

commands.getoutput("ls")
commands.getstatus("ls")

⑤ python+函數的返回值能不能直接輸出

在Python中,一個函伏陪數的返回值可以直接輸出,示例代碼如下:

# 定義一個函數

def add(a, b):

return a + b

# 調用函數並輸出返回值

print(add(1, 2))

在這段代碼中,我們首先定義了一個名為add的函數,該函數接收兩個參數a和b,並通過return語句返回它們的和。缺滾蠢接著,備扮我們調用該函數並傳入參數1和2,並使用print函數輸出函數的返回值,即3。

請注意,上面的代碼只是一個示例,實際應用中可能需要根據實際情況進行更多的處理,比如考慮函數沒有返回值等情況。

熱點內容
安卓系統網路播放器哪個好 發布:2025-02-06 20:42:02 瀏覽:814
頭條緩存的視頻格式 發布:2025-02-06 20:32:18 瀏覽:115
ftp不顯示文件夾 發布:2025-02-06 20:30:37 瀏覽:126
蘋果手機解壓怎麼打開 發布:2025-02-06 20:29:35 瀏覽:475
單片機程序存儲器 發布:2025-02-06 20:29:31 瀏覽:208
串的c語言 發布:2025-02-06 20:25:44 瀏覽:749
編程函數總結 發布:2025-02-06 20:09:11 瀏覽:316
編程obj 發布:2025-02-06 19:59:52 瀏覽:844
津貼腳本 發布:2025-02-06 19:44:10 瀏覽:741
好分數里如何修改密碼 發布:2025-02-06 19:42:30 瀏覽:157