python進程和線程

------------------------------線程---------------------------
#線程應用的第一種方式:thread模塊是比較底層的模塊
#import thread:引用的模塊
#thread.start_new_thread(defName,()):線程的建立
#thread.exit_thread():線程的結束python


#線程應用的第二種方式:threading模塊是對thread作了一些包裝,能夠更方便被引用
#import threading:引用的模塊
#myThread=threading.Thread(target=defName,args=('Alice',)):線程的建立
#myThread.start():線程開始執行
#num=len(threading.enumerate):線程數量的查看安全

#線程應用的第三種方式:建立一個線程類,繼承基類:threading.Thread 。重寫def run(self):方法。須要運行的內容,寫在run方法裏面。
#class MyThread(threading.Thread):建立類的對象
#能夠進行重構函數的對應擴展:def __init__(self,name,time):threading.Thread.__init__(self,name='對應的線程名字')
#myThread=MyThread():建立對象
#myThread.start():線程開始執行服務器

 

------------------------------線程同步之互斥鎖---------------------------
#線程同步之互斥鎖
#互斥鎖同步:線程同步可以保證多個線程安全訪問競爭資源,最簡單的同步機制是引用互斥鎖。互斥鎖爲資源引入一個狀態:鎖定/非鎖定。某個線程要更改共享數據時,先將其鎖定,此時資源的狀態爲「鎖定」,其餘線程不能更改;直到該線程釋放資源,將資源的狀態變成「非鎖定」,其餘的線程才能再次鎖定該資源。socket

#mutex=threading.Lock():建立互斥鎖
#if mutex.acquire([blocking]):互斥鎖鎖定狀態,返回值不爲0表示上鎖成功
# 鎖定方法acquire能夠有一個blocking參數。若是設定blocking爲True,則當前線程會堵塞,直到獲取到這個鎖爲止(若是沒有指定,那麼默認爲True);若是設定blocking爲False,則當前線程不會堵塞
#mutex.release():互斥鎖釋放狀態tcp

 


------------------------------線程同步至可重入鎖---------------------------
#線程同步之可重入鎖
#RLock內部維護着一個Lock和一個counter變量,counter記錄了acquire的次數,從而使得資源能夠被屢次acquire。直到一個線程全部的acquire都被release,其餘的線程才能得到資源:
#mutex=threading.RLock():建立可重入鎖
#mutex.acquire():可重入鎖鎖定狀態
#mutex.release():可重入鎖釋放狀態ide

 

------------------------------線程同步之條件變量---------------------------
#線程同步之條件變量
#Python提供的Condition對象提供了對複雜線程同步問題的支持。Condition被稱爲條件變量,除了提供與Lock相似的acquire和release方法外,還提供了wait和notify方法。線程首先acquire一個條件變量,而後判斷一些條件。若是條件不知足則wait;若是條件知足,進行一些處理改變條件後,經過notify方法通知其餘線程,其餘處於wait狀態的線程接到通知後會從新判斷條件。不斷的重複這一過程,從而解決複雜的同步問題。函數

#Condition對象維護了一個鎖(Lock/RLock)和一個waiting池。線程經過acquire得到Condition對象,當調用wait方法時,線程會釋放Condition內部的鎖並進入blocked狀態,同時在waiting池中記錄這個線程。當調用notify方法時,Condition對象會從waiting池中挑選一個線程,通知其調用acquire方法嘗試取到鎖。ui

#Condition對象的構造函數能夠接受一個Lock/RLock對象做爲參數,若是沒有指定,則Condition對象會在內部自行建立一個RLock。spa

#除了notify方法外,Condition對象還提供了notifyAll方法,能夠通知waiting池中的全部線程嘗試acquire內部鎖。因爲上述機制,處於waiting狀態的線程只能經過notify方法喚醒,因此notifyAll的做用在於防止有線程永遠處於沉默狀態。操作系統

#con=threading.Condition():建立條件變量
#con.acquire():條件變量鎖定狀態
#con.wait():線程釋放Condition內部的鎖並進入blocked狀態,同時在waiting池中記錄這個線程
#con.notify():Condition對象會從waiting池中挑選一個線程,通知其調用acquire方法嘗試取到鎖
#con.notifyAll():喚醒全部處於waiting池中的全部線程,防止有線程永遠處於沉默狀態
#con.release():條件變量釋放狀態

 


------------------------------線程同步之隊列---------------------------
#from Queue import Queue:進行對應的隊列包的引用
#queue=Queue():隊列的建立
#queue.qsize():獲取隊列中內容的數量
#queue.put(內容):向隊列中添加對應的數據信息
#queue.set():從隊列中取出對應的數據
#queue.empty():查看當前隊列內容是否爲空

 1 #引入對應的包
 2 import threading  3 
 4 from Queue import Queue  5 
 6 from time import sleep  7 
 8 #線程生產者
 9 class Producer(threading.Thread): 10     #重寫run方法
11     def run(self): 12         global g_queue 13 
14         while True: 15             if con.acquire(): 16                 #判斷是否中止生產,獲取隊列中的數量
17                 if g_queue.qsize() < 20: 18 
19                     #每次生產5個產品
20                     for i in range(5): 21                         g_queue.put("產品") 22 
23                     print("生產出5個產品,產品總量:%d"%g_queue.qsize()) 24                 else: 25  con.wait() 26                     print("中止生產") 27 
28  con.release() 29             sleep(1) 30 
31 
32 #線程消費者
33 class Consumer(threading.Thread): 34     #重寫run方法
35     def run(self): 36         global g_queue 37 
38         while True: 39             if con.acquire(): 40                 #判斷是否中止消費
41                 if g_queue.qsize()>5: 42                     #進行消費
43                     for i in range(3): 44  g_queue.get() 45 
46                     print("消費3 總數:%d"%g_queue.qsize()) 47 
48                     if g_queue.qsize()<20: 49  con.notify() 50  con.release() 51             sleep(1) 52 
53 #全局變量
54 con=threading.Condition() 55 #g_num=600
56 #建立一個隊列
57 g_queue=Queue() 58 
59 
60 #main函數
61 def main(): 62     pro=Producer() 63  pro.start() 64     con=Consumer() 65  con.start() 66 
67 #程序入口
68 if __name__ == '__main__': 69  main() 70 
71 線程隊列實現生產者消費者
View Code

------------------------------線程間通訊---------------------------

threading.Event能夠使一個線程等待其餘線程的通知。其內置了一個標誌,初始值爲False。線程經過wait()方法進入等待狀態,直到另外一個線程調用set()方法將內置標誌設置爲True時,Event通知全部等待狀態的線程恢復運行。還能夠經過isSet()方法查詢Envent對象內置狀態的當前值。

#event=threading.Event():進行對應Envent對象的建立
#self.threadEvent=event :重構對應threading.Thread基類中的__init__的方法。
#self.threadEvent.wait():使線程進入等待狀態
#event.set():啓動waiting池中等待的線程

 


------------------------------線程的合併和後臺線程---------------------------
python的Thread類中還提供了join()方法,使得一個線程能夠等待另外一個線程執行結束後再繼續運行。這個方法還能夠設定一個timeout參數,避免無休止的等待。由於兩個線程順序完成,看起來象一個線程,因此稱爲線程的合併。
默認狀況下,主線程在退出時會等待全部子線程的結束。若是但願主線程不等待子線程,而是在退出時自動結束全部的子線程,就須要設置子線程爲後臺線程(daemon)。方法是經過調用線程類的setDaemon()方法。

#myThread.setDaemon(True):將該線程轉爲後臺線程

 


------------------------------ThreadLocal---------------------------
global_dict={}
global_dict[threading.current_thread()]

 


------------------------------多進程---------------------------
在Unix/Linux操做系統中,提供了一個fork()系統函數,它很是特殊。

普通的函數調用,調用一次,返回一次,可是fork()調用一次,返回兩次,由於操做系統自動把當前進程(稱爲父進程)複製了一份(稱爲子進程),而後,分別在父進程和子進程內返回。

子進程永遠返回0,而父進程返回子進程的ID。

這樣作的理由是,一個父進程能夠fork出不少子進程,因此,父進程要記下每一個子進程的ID,而子進程只須要調用getppid()就能夠拿到父進程的ID。

#import os :引用對應的進程包

#pid=os.fork():程序執行到os.fork()時,操做系統會建立一個新的進程(子進程),而後複製父進程的全部信息到子進程中,而後父進程和子進程都會從fork()函數中獲得一個返回值,其進程中這個值必定是0,而父進程中是子進程的 id號

#os.getpid():獲取當前進程的pid
#os.getppid():獲取父進程的pid

 

------------------------------multiprocessing模塊---------------------------
#from multiprocessing import Process:multiprocessing模塊提供了一個Process類來表明一個進程對象。
#p=Process(target=run_proc,args=('test',)):建立對應的進程對象
#p.start():進程的啓動
#p.join():multiprocessing模塊提供了一個Process類來表明一個進程對象,下面的例子演示了啓動一個子進程並等待其結束
#multiprocessing.cpu_count():查看對應的cpu核數
#pipe=multiprocessing.Pipe():建立一個管道,管道兩個端口調用分別爲pipe[0],pipe[1]
#pipe[0].send(i):爲管道一側進行內容的添加操做
#pipe[0].recv():獲取管道一側的內容信息

 1 #coding=utf-8
 2 
 3 #引用對應的包
 4 from socket import *
 5 
 6 from multiprocessing import Process  7 
 8 import sys  9 
10 #進程函數:爲客戶提供tcp服務
11 def tcpClient(newSocket,destAddr): 12     print("客戶端(%s)以上線"%str(destAddr)) 13     while True: 14         #數據的接受
15         recvData=newSocket.recv(1024) 16         #模擬echo將數據回發服務器
17  newSocket.send(recvData) 18         
19         #若是接收的數據長度爲0,進行客戶端的關閉操做
20         if len(recvData) <= 0: 21             print("------客戶端(%s)已經下線-------"%str(destAddr)) 22             
23  newSocket.close() 24             break        
25         print ("客戶端(%s)傳遞過的數據爲:%s"%(str(destAddr),recvData)) 26 
27 
28 #函數:main
29 def main(): 30     #建立Tcp套接字
31     socTcpSer=socket(AF_INET,SOCK_STREAM) 32 
33     socTcpSer.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 34 
35     #建立ip和端口進行綁定
36     local=("",int(sys.argv[1])) 37  socTcpSer.bind(local) 38 
39     #開啓監聽程序
40     socTcpSer.listen(5) 41 
42     print('---------等待客戶端上線---------') 43     
44     #進行服務的開啓,並循環爲客戶進行服務
45     while True: 46 
47         #接受客戶端響應信息
48         newSocket,destAddr=socTcpSer.accept() 49         
50         #建立子進程
51         pClient=Process(target=tcpClient,args=(newSocket,destAddr,)) 52         
53         #子進程開始
54  pClient.start() 55 
56  socTcpSer.close() 57 
58 
59 #程序入口
60 if __name__=='__main__': 61  main() 62 
63 多進程實現tcp服務 64 
65 多進程模擬tcp服務
View Code
相關文章
相關標籤/搜索