淺談python多線程和隊(duì)列管理shell程序
首先來描述下環(huán)境,在機(jī)器上有很多個(gè)JAVA程序,我們在每個(gè)JAVA程序里都配置了一個(gè)啟動(dòng)|停止|重啟的腳本
舉個(gè)例子:
我們現(xiàn)在要同時(shí)運(yùn)行這些腳本,來達(dá)到快速啟動(dòng)所有的JAVA程序,如果我們只用多線程的話,線程是不會(huì)返回消息給父進(jìn)程,我們?nèi)绾尾拍苤肋@些程序是啟動(dòng)成功了呢?
所以我們用到了隊(duì)列來管理。
"""我試過gevent,但是會(huì)在command這里造成阻塞"""
gevent代碼如下 如果有朋友知道如何優(yōu)化,請您告訴我
#!/usr/bin/python2.7
# -*- coding:utf-8 -*-
import os,sys
from datetime import datetime
import commands
import gevent.monkey
gevent.monkey.patch_os()
import gevent
def Servers():
servers=commands.getoutput('''ls /data/program/payment/ | grep 'payment' ''')
servers=servers.split('\n')
return servers
def handle(servername):
if sys.argv[1] == 'start' or sys.argv[1] == 'stop' or sys.argv[1] == 'restart':
print '\033[1;31;40m'
print '========================>>>go to handle %s<<<=========================' %servername
print '\033[0m'
r=commands.getoutput('''su - tomcat -c "/data/program/payment/%s/bin/server.sh %s &" ''' %(servername,sys.argv[1])) #在這里會(huì)阻塞,我們無法找到合適的地方進(jìn)行協(xié)程的切換
gevent.sleep(0) #無論放到何處,不是之前就是切換之后都會(huì)阻塞。
print r
else:
print 'Please Use start | stop | restart To Handle The Command'
sys.exit(1)
if __name__ == '__main__':
s=Servers()
threads=[]
for i in s:
threads.append(gevent.spawn(handle,i))
# print threads
gevent.joinall(threads)
多線程代碼如下
#!/usr/bin/python2.7
# -*- coding:utf-8 -*-
from datetime import datetime
import commands
from Queue import Queue
from threading import Thread
_sentinel = object()
def Servers():
servers=commands.getoutput('''ls /data/program/payment/ | grep 'payment' ''')
servers=servers.split('\n')
return servers
def producer(servername,out_q):
if sys.argv[1] == 'start' or sys.argv[1] == 'stop' or sys.argv[1] == 'restart':
print '\033[1;31;40m'
print '========================>>>put %s in Queue<<<=========================' %servername
print '\033[0m'
out_q.put_nowait(commands.getoutput('''su - tomcat -c "/data/program/payment/%s/bin/server.sh %s &" ''' %(servername,sys.argv[1]))) #放入隊(duì)列的對象
else:
print 'Please Use start | stop | restart To Handle The Command'
sys.exit(1)
def consumer(servername,in_q):
n=len(servername)
while n > 0: #循環(huán)在隊(duì)列中取結(jié)果,直到循環(huán)結(jié)束
data=in_q.get()
n -= 1
print '\033[1;31;40m'
print data
print '\033[0m'
print '\033[1;31;40m'
print 'consumer was done!!!!!!!'
print '\033[0m'
if __name__ == '__main__':
s=Servers()
q = Queue()
t1 = Thread(target=consumer, args=(s,q,)) #消費(fèi)者在隊(duì)列中獲取結(jié)果,前面的函數(shù)內(nèi)部已經(jīng)循環(huán)獲取
for i in s:
t2=Thread(target=producer, args=(i,q,)) #講線程進(jìn)行管理,放入隊(duì)列
t2.start() #啟動(dòng)生產(chǎn)者線程
# t2.join() #啟動(dòng)生產(chǎn)者以后放棄校驗(yàn)線程是否結(jié)束,進(jìn)行并發(fā),因?yàn)槲覀兪前丫€程放入隊(duì)列進(jìn)行管理的,所以不用在這里等待線程結(jié)束,如果使用了join這里會(huì)阻塞我們的程序。線程結(jié)束后,消費(fèi)者會(huì)通知父進(jìn)程線程已經(jīng)結(jié)束。
t1.start() #啟動(dòng)消費(fèi)者線程
t1.join() #在獲取完成之前進(jìn)行線程的阻塞
簡單的說下join這個(gè)方法:
調(diào)用Thread.join將會(huì)使主調(diào)線程堵塞,直到被調(diào)用線程運(yùn)行結(jié)束或超時(shí)。參數(shù)timeout是一個(gè)數(shù)值類型,表示超時(shí)時(shí)間,如果未提供該參數(shù),那么主調(diào)線程將一直堵塞到被調(diào)線程結(jié)束。
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
Jupyter Notebook/VSCode導(dǎo)出PDF中文不顯示的解決
這篇文章主要介紹了Jupyter Notebook/VSCode導(dǎo)出PDF中文不顯示的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Python標(biāo)準(zhǔn)庫json模塊和pickle模塊使用詳解
這篇文章主要介紹了Python標(biāo)準(zhǔn)庫json模塊和pickle模塊使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Python實(shí)現(xiàn)查詢某個(gè)目錄下修改時(shí)間最新的文件示例
這篇文章主要介紹了Python實(shí)現(xiàn)查詢某個(gè)目錄下修改時(shí)間最新的文件,涉及Python使用os與shutil模塊針對文件的遍歷、屬性獲取、讀寫等相關(guān)操作技巧,需要的朋友可以參考下2018-08-08
使用Dajngo 通過代碼添加xadmin用戶和權(quán)限(組)
這篇文章主要介紹了使用Dajngo 通過代碼添加xadmin用戶和權(quán)限(組),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
使用Python進(jìn)行大規(guī)模數(shù)據(jù)處理和分析
大規(guī)模數(shù)據(jù)處理和分析旨在從海量數(shù)據(jù)中提取有用的信息和見解,以支持決策制定和業(yè)務(wù)發(fā)展,Python憑借其豐富的生態(tài)系統(tǒng)和強(qiáng)大的庫,為處理和分析數(shù)據(jù)提供了豐富的工具和資源,在本文中,我們將深入探討如何利用Python進(jìn)行大規(guī)模數(shù)據(jù)處理和分析,需要的朋友可以參考下2024-05-05

