日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python的进程模块

發布時間:2024/9/15 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python的进程模块 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 進程與線程
    • 進程定義:
    • 線程定義
    • 線程進程的關系區別
      • 1.直接調用
      • 2.繼承式調用
      • 3.threading.thread實例方法
          • join() :
            • 情況1:
            • 情況2:
          • Daemon() :守護線程
    • 同步鎖
    • 死鎖和遞歸鎖
    • 事件event
    • 信號量(控制同時可以運行的線程)
  • 隊列——多線程利器
    • 創建一個“隊列”對象
    • 生產者消費者模型
  • 多進程模塊multiprocessing
    • 每秒鐘運行3個
    • show the individual process IDs involved
    • Process類
    • 進程間通信
      • 通過隊列
      • 通過管道
      • 信息共享 manager

進程與線程

假如有兩個程序A和B,程序A在執行到一半的過程中,需要讀取大量的數據輸入(I/O操作),而此時CPU只能靜靜地等待任務A讀取完數據才能繼續執行,這樣就白白浪費了CPU資源。是不是在程序A讀取數據的過程中,讓程序B去執行,當程序A讀取完數據之后,讓程序B暫停,然后讓程序A繼續執行?當然沒問題,但這里有一個關鍵詞:切換。
切換,那么這就涉及到了狀態的保存,狀態的恢復,加上程序A與程序B所需要的系統資源(內存,硬盤,鍵盤等等)是不一樣的。自然而然的就需要有一個東西去記錄程序A和程序B分別需要什么資源,怎樣去識別程序A和程序B等等,所以就有了一個叫進程的抽象。

進程定義:

進程就是一個程序在一個數據集上的一次動態執行過程。
進程一般由程序、數據集、進程控制塊三部分組成。

舉一例說明進程:
想象一位有一手好廚藝的計算機科學家正在為他的女兒烘制生日蛋糕。他有做生日蛋糕的食譜,廚房里有所需
的原料:面粉、雞蛋、糖、香草汁等。在這個比喻中,做蛋糕的食譜就是程序(即用適當形式描述的算法)計算機科學家就是處理器(cpu),
而做蛋糕的各種原料就是輸入數據。進程就是廚師閱讀食譜、取來各種原料以及烘制蛋糕等一系列動作的總和。
現在假設計算機科學家的兒子哭著跑了進來,說他的頭被一只蜜蜂蟄了。計算機科學家就記錄下他
照著食譜做到哪兒了(保存進程的當前狀態),然后拿出一本急救手冊,按照其中的指示處理蟄傷。這
里,我們看到處理機從一個進程(做蛋糕)切換到另一個高優先級的進程(實施醫療救治),每個進程
擁有各自的程序(食譜和急救手冊)。當蜜蜂蟄傷處理完之后,這位計算機科學家又回來做蛋糕,從他
離開時的那一步繼續做下去。

線程定義

線程的出現是為了降低上下文切換的消耗,提高系統的并發性,并突破一個進程只能干一樣事的缺陷,
使到進程內并發成為可能。

假設,一個文本程序,需要接受鍵盤輸入,將內容顯示在屏幕上,還需要保存信息到硬盤中。若只有
一個進程,勢必造成同一時間只能干一樣事的尷尬(當保存時,就不能通過鍵盤輸入內容)。若有多
個進程,每個進程負責一個任務,進程A負責接收鍵盤輸入的任務,進程B負責將內容顯示在屏幕上的
任務,進程C負責保存內容到硬盤中的任務。這里進程A,B,C間的協作涉及到了進程通信問題,而且
有共同都需要擁有的東西-------文本內容,不停的切換造成性能上的損失。若有一種機制,可以使
任務A,B,C共享資源,這樣上下文切換所需要保存和恢復的內容就少了,同時又可以減少通信所帶
來的性能損耗,那就好了。是的,這種機制就是線程。

線程也叫輕量級進程,它是一個基本的CPU執行單元,也是程序執行過程中的最小單元,由線程ID、程序
計數器、寄存器集合和堆棧共同組成。線程的引入減小了程序并發執行時的開銷,提高了操作系統的并發
性能。線程沒有自己的系統資源。

線程進程的關系區別

1.Threads share the address space of the process that created it; processes have their own address space. 線程共享創建它的進程的地址空間;進程們有它們各自的地址空間 2.Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process. 線程們可以直接訪問它的進程數據;進程們有它們父進程的數據拷貝 3.Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes. 線程能夠直接與其進程的其他線程交流;進程間的交流需要用交互進程才能與他們的近鄰進程交流 4.New threads are easily created; new processes require duplication of the parent process. 新縣城能容易創建;新進程需要復制父進程 5.Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes. 線程可以在同一進程的線程上執行大量操作;進程只能作業于子進程 6.Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes. 對主線程的改變(取消,權限變更等...)可能會影響同一進程的其他線程的表現;對父進程的改變不會影響子進程

1.一個程序至少有一個進程,一個進程至少有一個線程.(進程可以理解成線程的容器)
2.進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
3.線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
4.進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.
5.線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧)但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
6.一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以并發執行.

python的GIL

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

上面的核心意思就是,無論你啟多少個線程,你有多少個cpu, Python在執行的時候會淡定的在同一時刻只允許一個線程運行

python的線程和threading模塊

線程調用的兩種模式:直接調用、繼承式調用

1.直接調用

import threading import timedef speaksth(num):#定義函數用于線程運行print('start running threading%d' %num)time.sleep(num)if __name__=='__main__':t1 = threading.Thread(target=speaksth,args=(1,))#生成一個線程實例t2 = threading.Thread(target=speaksth,args=(2,))#生成另一個線程實例t1.start()t2.start()print(t1.getName())#獲取線程名print(t2.getName()) # 獲取線程名print('end'.center(20,'-'))

2.繼承式調用

import threading import timeclass m_thread(threading.Thread):def __init__(self,num,time):self.num = numself.time= timethreading.Thread.__init__(self)def run(self):#定義每個線程的運行函數print('running on num:%s' %self.num)time.sleep(self.time)print('num:%s end'.center(20,'^') %self.num)if __name__ == '__main__':t1 = m_thread(1,3)t2 = m_thread(2,5)t1.start()t2.start()print("main threading end".center(20,'-'))

3.threading.thread實例方法

.join()要加在線程.start()之后,先線程1.start()主線程一碰到 線程1.join()就停下來等待。

join() :

在子線程完成運行之前,這個子線程的父線程將一直被阻塞。在這個線程運行結束之前,其他線程等待。

情況1:
import threading from time import ctime,sleep import timedef ListenMusic(name):print("begin listening to %s. %s" %(name,ctime()))sleep(3)print("end listening %s"%ctime()) def RecordBlog(title):print("Begin recording the %s %s" %(title,ctime()))sleep(5)print("end recording %s"%ctime())threads = [] for i in range(5):threads.append(threading.Thread(target=ListenMusic,args=(str(i),)))if __name__ == '__main__':for t in threads:t.start()t.join()print("End main thread %s"%ctime())


即,一個運行完再到另一個

情況2:
import threading from time import ctime,sleep import time def ListenMusic(name):print("begin listening to %s. %s" %(name,ctime()))sleep(3)print("end listening %s"%ctime()) def RecordBlog(title):print("Begin recording the %s %s" %(title,ctime()))sleep(5)print("end recording %s"%ctime())threads = [] for i in range(5):threads.append(threading.Thread(target=ListenMusic,args=(str(i),)))if __name__ == '__main__':for t in threads:t.start()#t.join()print("End main thread %s"%ctime())

Daemon() :守護線程

setDaemon(True):
將線程聲明為守護線程,必須在start() 方法調用之前設置, 如果不設置為守護線程程序會被無限掛起。這個方法基本和join是相反的。 當我們在程序運行中,執行一個主線程,如果主線程又創建一個子線程,主線程和子線程就分兵兩路,分別運行,那么當主線程完成想退出時,會檢驗子線程是否完成。如果子線程未完成,則主線程會等待子線程完成后再退出。但是有時候我們需要的是只要主線程完成了,不管子線程是否完成,都要和主線程一起退出,這時就可以用setDaemon方法啦
例子:

import threading from time import ctime,sleep import time def ListenMusic(name):print("begin listening to %s. %s" %(name,ctime()))sleep(3)print("end listening %s"%ctime()) def RecordBlog(title):print("Begin recording the %s %s" %(title,ctime()))sleep(5)print("end recording %s"%ctime()) threads = [] for i in range(5):threads.append(threading.Thread(target=ListenMusic,args=(str(i),)))if __name__ == '__main__':for t in threads:t.setDaemon(True) #一定要在start之前設置t.start()print("End main thread %s"%ctime())

一瞬間執行完畢,不等子線程運行完成。

同步鎖

import time import threading def addNum():global num #在每個線程中都獲取這個全局變量#num-=1temp=num#print('--get num:',num )time.sleep(0.1)num =temp-1 #對此公共變量進行-1操作num = 100 #設定一個共享變量 thread_list = [] for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list: #等待所有線程執行完畢t.join()print('final num:', num )


改變time.sleep()的時間

import time import threading def addNum():global num #在每個線程中都獲取這個全局變量#num-=1temp=num#print('--get num:',num )time.sleep(0.0001)num =temp-1 #對此公共變量進行-1操作num = 100 #設定一個共享變量 thread_list = [] for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list: #等待所有線程執行完畢t.join()print('final num:', num )


鎖原理圖:
當time.sleep(0.1)變化時 /0.001/0.0000001
多個線程都在同時操作同一個共享資源,所以造成了資源破壞,怎么辦呢?(join會造成串行,失去所線程的意義)

我們可以通過同步鎖來解決這種問題

import time import threading R = threading.Lock()# 同步鎖 def addNum():global num #在每個線程中都獲取這個全局變量#num-=1R.acquire()#獲取鎖temp=num#print('--get num:',num )time.sleep(0.0001)num =temp-1 #對此公共變量進行-1操作R.release()#解鎖num = 100 #設定一個共享變量 thread_list = [] for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list: #等待所有線程執行完畢t.join()print('final num:', num )

死鎖和遞歸鎖

事件event

An event is a simple synchronization object;the event represents an internal flag,

and threads can wait for the flag to be set, or set or clear the flag themselves.
event = threading.Event()

a client thread can wait for the flag to be set
event.wait()

a server thread can set or reset it
event.set()
event.clear()

If the flag is set, the wait method doesn’t do anything.
If the flag is cleared, wait will block until it becomes set again.
Any number of threads may wait for the same event.

import threading,time class Boss(threading.Thread):def run(self):print('老板發話了嗎?',event_ganhuo.isSet())# Falsetime.sleep(1)print("BOSS:今晚大家都要加班到22:00。")event_ganhuo.set()print('老板發話了嗎?',event_ganhuo.isSet())# Truetime.sleep(5)print('老板說下班了嗎?',event_xiaban.isSet())# Falsetime.sleep(1)print("BOSS:<22:00>可以下班了。")event_xiaban.set()print('老板說下班了嗎?',event_xiaban.isSet())# Trueclass Worker(threading.Thread):def run(self):event_ganhuo.wait()# 一旦event被設定,等同于passtime.sleep(1)print("Worker:哎……命苦啊!")time.sleep(1)event_xiaban.wait()time.sleep(1)print("Worker:OhYeah!")if __name__=="__main__":event_ganhuo=threading.Event()event_xiaban=threading.Event()threads=[]for i in range(5):threads.append(Worker())threads.append(Boss())for t in threads:t.start()for t in threads:t.join()print("ending.....")

運行結果:

信號量(控制同時可以運行的線程)

信號量用來控制線程并發數的,BoundedSemaphore或Semaphore管理一個內置的計數 器,每當調用acquire()時-1,調用release()時+1。

import threading,time class myThread(threading.Thread):def run(self):if semaphore.acquire():print(self.name)time.sleep(2)semaphore.release() if __name__=="__main__":semaphore=threading.Semaphore(5)#每次能運行的線程thrs=[]for i in range(100):thrs.append(myThread())for t in thrs:t.start()

線程每隔2秒出現5個

隊列——多線程利器

保證線程安全。
有線程隊列也有進程隊列

創建一個“隊列”對象

import Queue
q = Queue.Queue(maxsize = 10)
Queue.Queue類即是一個隊列的同步實現。隊列長度可為無限或者有限。可通過Queue的構造函數的可選參數maxsize來設定隊列長度。如果maxsize小于1就表示隊列長度無限。

將一個值放入隊列中
q.put(10)
調用隊列對象的put()方法在隊尾插入一個項目。put()有兩個參數,第一個item為必需的,為插入項目的值;第二個block為可選參數,默認為
1。如果隊列當前為空且block為1,put()方法就使調用線程暫停,直到空出一個數據單元。如果block為0,put方法將引發Full異常。

將一個值從隊列中取出
q.get()
調用隊列對象的get()方法從隊頭刪除并返回一個項目。可選參數為block,默認為True。如果隊列為空且block為True,
get()就使調用線程暫停,直至有項目可用。如果隊列為空且block為False,隊列將引發Empty異常。

Python Queue模塊有三種隊列及構造函數:
1、Python Queue模塊的FIFO隊列先進先出。 class queue.Queue(maxsize)
2、LIFO類似于堆,即先進后出。 class queue.LifoQueue(maxsize)
3、還有一種是優先級隊列級別越低越先出來。 class queue.PriorityQueue(maxsize)

此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回隊列的大小
q.empty() 如果隊列為空,返回True,反之False
q.full() 如果隊列滿了,返回True,反之False
q.full 與 maxsize 大小對應
q.get([block[, timeout]]) 獲取隊列,timeout等待時間
q.get_nowait() 相當q.get(False)
非阻塞 q.put(item) 寫入隊列,timeout等待時間
q.put_nowait(item) 相當q.put(item, False)
q.task_done() 在完成一項工作之后,q.task_done() 函數向任務已經完成的隊列發送一個信號
q.join() 實際上意味著等到隊列為空,再執行別的操作

import queue import time q = queue.Queue(3) #創建隊列默認first in first out,只能存3個隊列q.put(12) q.put('hello') q.put({'name':'AFf'}) #q.put(34) #再加這一步會一直卡住,因為只能有3個 #q.put(34,False) #不會卡住,但是報錯while 1:data = q.get(block=False)#隊列為空時,取不出則報錯time.sleep(1)print(data)

優先級隊列

import queue import time q = queue.PriorityQueue() #創建隊列默認first in first out,只能存3個隊列 q.put([3,12]) q.put([2,'hello']) q.put([4,{'name':'AFf'}]) #q.put(34) #再加這一步會一直卡住,因為只能有3個 #q.put(34,False) #不會卡住,但是報錯while 1:data = q.get()#隊列為空時,取不出則報錯time.sleep(1)print(data)

生產者消費者模型

import queue,threading import time import random q = queue.Queue()def Producer(name):count = 0while count<5:print('begin produce bread')count += 1print('\033[32;1m%s has produced %d bread\033[0m'%(name,count))time.sleep(2)q.put(count)print('round end'.center(20,'-'))def Consumer(name):data = 0while data<5:time.sleep(random.randint(1,2))if q.qsize()>0:print('begin eat bread'.center(20,'^'))data = q.get()print('%s has eat a bread')else:print("-----no baozi anymore----")p1 = threading.Thread(target=Producer,args=('abc',)) c1 = threading.Thread(target=Consumer,args=('guest',)) p1.start() c1.start()

多進程模塊multiprocessing

Multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency,effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

每秒鐘運行3個

from multiprocessing import Process import time def f(name):time.sleep(1)print('hello', name,time.ctime())if __name__ == '__main__':p_list=[]for i in range(3):for j in range(3):p = Process(target=f, args=('alvin',))p_list.append(p)p.start()for i in p_list:p.join()print('end')

show the individual process IDs involved

from multiprocessing import Process import os import timedef info(title):print("title:", title)print('parent process:', os.getppid())print('process id:', os.getpid())def f(name):info('function f')print('hello', name)if __name__ == '__main__':info('main process line')time.sleep(1)print("------------------")p = Process(target=info, args=('yuan',))p.start()p.join()

Process類

構造方法:
Process([group [, target [, name [, args [, kwargs]]]]])
  group: 線程組,目前還沒有實現,庫引用中提示必須是None;
  target: 要執行的方法;
  name: 進程名;
  args/kwargs: 要傳入方法的參數。
實例方法:
  is_alive():返回進程是否在運行。
  join([timeout]):阻塞當前上下文環境的進程程,直到調用此方法的進程終止或到達指定的timeout(可選參數)。
  start():進程準備就緒,等待CPU調度
  run():strat()調用run方法,如果實例進程時未制定傳入target,這star執行t默認run()方法。
  terminate():不管任務是否完成,立即停止工作進程
屬性:
  daemon:和線程的setDeamon功能一樣
  name:進程名字。
  pid:進程號。

import time from multiprocessing import Process class MyProcess(Process):def __init__(self,num):super(MyProcess,self).__init__()#繼承父類的初始化字段self.num = numdef run(self):time.sleep(1)print(self.pid)print(p.is_alive())print(self.num)time.sleep(1)if __name__ == '__main__':p_list=[]for i in range(10):p = MyProcess(i)#p.daemon=Truep_list.append(p)for p in p_list:p.start()print('main process end')

進程間通信

通過隊列

import time # #import queue #進程間的通信不能用線程隊列 import multiprocessing def foo(q):time.sleep(1)print("son process",id(q))#打印q的idq.put(123)q.put("yuan") if __name__ == '__main__':#q=queue.Queue()q=multiprocessing.Queue()p=multiprocessing.Process(target=foo,args=(q,))#傳一個進程隊列q過去p.start()#p.join()print("main process",id(q))print(q.get())print(q.get())

通過管道

from multiprocessing import Process, Pipe def f(conn):conn.send([12, {"name":"yuan"}, 'hello'])response=conn.recv()print("response",response)conn.close()print("q_ID2:",id(conn))if __name__ == '__main__':parent_conn, child_conn = Pipe() #雙向管道print("q_ID1:",id(child_conn))p = Process(target=f, args=(child_conn,))p.start()print(parent_conn.recv()) #父進程等待,如果沒有收到將會阻塞, prints "[42, None, 'hello']"parent_conn.send("兒子你好!")p.join()

信息共享 manager

from multiprocessing import Process, Manager def f(d, l,n):d[n] = '1' #{0:"1"}d['2'] = 2 #{0:"1","2":2}l.append(n) #[0,1,2,3,4, 0,1,2,3,4,5,6,7,8,9]#print(l)if __name__ == '__main__':with Manager() as manager:d = manager.dict()#{}l = manager.list(range(5))#[0,1,2,3,4]p_list = []for i in range(10):p = Process(target=f, args=(d,l,i))p.start()p_list.append(p)for res in p_list:res.join()print(d)print(l)

參考鏈接:
http://www.cnblogs.com/yuanchenqi/articles/6248025.html

總結

以上是生活随笔為你收集整理的python的进程模块的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。