Python--進程與線程

一,回顧操做系統的概念python

 操做系統位於底層硬件與應用軟件之間的一層git

 工做方式:向下管理軟件,向上提供接口github

二,進程線程的概念redis

  進程是一個資源單位,線程是一個最小的執行單位api

    一個線程只能屬於一個進程,而一個進程能夠有多個線程,但至少有一個線程多線程

三,並行與併發併發

並行:
    就是有多個進程能夠同時運行的叫作並行
併發:
    就是在一個處理器的狀況下,切換執行,叫作併發

python沒法實現並行處理,由於全局解釋器鎖gil致使同一時刻同一進程
只能有一個線程被運行。

    GIL全局解釋器鎖
    可是不影響Python開多進程

多線程代碼示例
    app

import threading
import time
'''
程序在運行是有一個主線程,當程序開啓多線程的時候,主線程依舊會執行,
主線程執行到最後時,並無結束,而是在等待子線程的結束後主線程結束

'''
def misc():
    print("聽歌")
    time.sleep(3)
    print("聽歌結束")


def xieboke():
    print("寫博客")
    time.sleep(5)
    print("寫博客結束")


#開啓線程
t1=threading.Thread(target=misc)#t1,t2是一個線程對象
t2=threading.Thread(target=xieboke)

t1.start()
t2.start()

print("主線程")

 



#開啓多線程的另外一種方式

函數

import threading
import time
class MyThread(threading.Thread):
    '''
    用類的繼承,繼承線程的方法開啓線程
    '''

    def __init__(self,num):
    '''
    繼承父類的__init__方法
    '''
        threading.Thread.__init__(self)
        self.num=num

    def run(self):
        print("running on mythread:%s"%self.num)
        time.sleep(3)
        print("end%s"%self.num)

t1=MyThread(10)
t2=MyThread(20)

t1.start()
t2.start()
print("主線程")

 



jion的使用
    t.jion方法會阻塞主進程的運行,但不會影響其餘線程的運行

setDaemon方法
    -守護線程
    當某個線程設置爲守護線程的時候,它會隨着主線程的結束而結束
    t.setDaemon(True)
    
線程對象下的幾個方法:
        -isAlive()檢測線程是否活動,返回值是布爾值
        -getName():返回線程名
        -setName():設置線程名稱
        
threading模塊提供的一些方法:
    threading.currentTread():返回當前線程變量
    threading.enumerate():返回一個包含正在運行的線程的list。
    threading.activeCount():返回正在運行的線程數量
    
Python對於計算密集型運行比較慢,效率低;對於IO密集型效率有明顯提升

Python多線程
    互斥鎖:
        互斥鎖的意義就是在保護鎖內代碼同一時間只有一個線程在使用
        直到代碼執行完成,解鎖後其餘線程才能執行所內代碼。
    使用格式:
        -lock=threading.Lock()建立一把鎖的對象
        lock.acquire()#加鎖
        ....須要保護的執行語句
        lock.release()#解鎖
    
    死鎖與遞歸鎖    
    代碼示例:
      ui

       import threading
        import time

        muteA=threading.Lock()
        muteB=threading.Lock()

        class MyThread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)

            def run(self):
                self.func1()
                self.func2()

            def func1(self):
                muteA.acquire()
                print("鎖A執行內容",MyThread.getName(self))
                muteB.acquire()
                print("鎖B執行內容",MyThread.getName(self))
                muteB.release()
                muteA.release()

            def func2(self):
                muteB.acquire()
                print("第二個函數的鎖B",MyThread.getName(self))
                muteA.acquire()
                print("第二個函數的鎖A",MyThread.getName(self))
                muteA.release()
                muteB.release()

        if __name__=="__main__":
            for i in range(10):
                my_thread=MyThread()
                my_thread.start()

 

            造成死鎖的緣由在於當線程1在第二個函數中拿到鎖B向下執行須要鎖A的時候,線程2在函數1中    已經拿到的鎖A,在等待線程1釋放B。兩個線程都沒有釋放另外一個線程須要的鎖,因此就造成了死鎖。            遞歸鎖的應用    遞歸鎖未避免死鎖的產生,在鎖內實行一個引用計數,當有一把使用是計速器加一,釋放後,去除計數    到代碼在執行鎖內代碼時,若是有其餘線程搶鎖,計數若是爲零,線程能夠拿到鎖,大於零,拒絕線程拿鎖    這樣就能避免鎖的重複,也就不會產生死鎖    代碼示例:        import threading        import time        Rlock=threading.Rlock()        class MyThread(threading.Thread):            def __init__(self):                threading.Thread.__init__(self)            def run(self):                self.func1()                self.func2()            def func1(self):                Rlock.acquire()                print("鎖A執行內容",MyThread.getName(self))                Rlock.acquire()                print("鎖B執行內容",MyThread.getName(self))                Rlock.release()                Rlock.release()            def func2(self):                Rlock.acquire()                print("第二個函數的鎖B",MyThread.getName(self))                Rlock.acquire()                print("第二個函數的鎖A",MyThread.getName(self))                Rlock.release()                Rlock.release()        if __name__=="__main__":            for i in range(10):                my_thread=MyThread()                my_thread.start()                event方法使用:    event方法可讓兩個線程之間通訊,當一個線程須要另外一個線程準備數據的時候,    event.wait(),阻塞程序的運行,直到另外一個線程將數據準備完成後,使用event.set()    返回一個true值,event.wait()接受到該值以後,線程開始運行。wait方法後能夠接一個超時    時間參數,規定在必定時間內阻塞,超時後運行。        import threading    import time    import logging    logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)    def worker(event):        logging.debug('Waiting for redis ready...')        while not event.isSet():            logging.debug("wait.......")            event.wait(3)   # if flag=False阻塞,等待flag=true繼續執行        logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())        time.sleep(1)    def main():        readis_ready = threading.Event()  #  flag=False建立一個event對象        t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')        t1.start()        t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')        t2.start()        logging.debug('first of all, check redis server, make sure it is OK, and then trigger the redis ready event')        time.sleep(6) # simulate the check progress        readis_ready.set()  # flag=Ture            if __name__=="__main__":        main()    進程multprocessing模塊    multprocessing模塊與threading模塊使用同一套api,使用方法調用方法與threading模塊同樣        代碼示例:    from multiprocessing import Process    import time    def f(name):        print("hello",name,time.ctime())        time.sleep(1)    if __name__=="__main__":        p_list=[]        for i in range(3):            p=Process(target=f,args=("alvin:%s"%i,))            p_list.append(p)            p.start()        協程的應用:    協程是單線程的,不能切換。由於協程對IO操做的判斷由本身控制    import time    #  能夠實現併發    def consumer():        r = ''        while True:            n = yield r            if not n:                return            print('[CONSUMER] ←← Consuming %s...' % n)            time.sleep(1)            r = '200 OK'    def produce(c):        next(c)        n = 0        while n < 5:            n = n + 1            print('[PRODUCER] →→ Producing %s...' % n)            cr = c.send(n)            print('[PRODUCER] Consumer return: %s' % cr)        c.close()    if __name__=='__main__':        c = consumer()        produce(c)    gevent模塊的使用:    from gevent import monkey    monkey.patch_all()    import gevent    from urllib import request    import time    def f(url):        print('GET: %s' % url)        resp = request.urlopen(url)        data = resp.read()        print('%d bytes received from %s.' % (len(data), url))    start=time.time()     gevent.joinall([             gevent.spawn(f, 'https://itk.org/'),             gevent.spawn(f, 'https://www.github.com/'),             gevent.spawn(f, 'https://zhihu.com/'),     ])    #f('https://itk.org/')    #f('https://www.github.com/')    #f('https://zhihu.com/')    print(time.time()-start)  

相關文章
相關標籤/搜索