day212223:線程、進程、協程

1、程序工作原理

?

?

進程的限制:每一個時刻只能有一個線程來工作。
多進程的優點:同時利用多個cpu,能夠同時進行多個操作。缺點:對內存消耗比較高
當進程數多于cpu數量的時候會導致不能被調用,進程不是越多越好,cpu與進程數量相等最好
線程:java和C# 對于一個進程里面的多個線程,cpu都在同一個時刻能使用。py同一時刻只能調用一個。
so:對于型的應用,py效率較java C#低。
多線程優點:共享進程的內存,可以創造并發操作。缺點:搶占資源,
多線程得時候系統在調用的時候需要記錄請求上下文的信息,請求上下文的切換 這個過程非常耗時。因此 線程不是越多越好,具體案例具體分析。
在計算機中,執行任務的最小單元就是線程
IO操作不利用CPU,IO密集型操作適合多線程,對于計算密集型適合多進程
GIL:全局解釋器鎖,PY特有它會在每個進程上加個鎖
系統存在進程和線程的目的是為了提高效率
1.1、單進程單線程
1.2、自定義線程:
主進程
主線程
子線程
2、線程鎖 threading.RLock和threading.Lock

多線程修改一個數據得時候可能會造成咱數據。建議使用rlock

3、線程時間:threading.Event: 通知
當有進程間的通訊的情況下這個才有應用場景。汽車類比線程,Event.wait()紅燈,Event.set()綠燈,Event.clear():使紅燈變綠

even是線程間的通訊機制。Event.wait([timeout]):賭賽線程,知道event對象內部標示位被設置為True或超時時間。Event.set():將標識位設為True。Event.clear():標識位設為False。Event.isSet():判斷標識位是否為True。

4、queue模塊:生產者-消費者模型

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import queue
import threading
# import queue# q = queue.Queue(maxsize=0)  # 構造一個先進顯出隊列,maxsize指定隊列長度,為0 時,表示隊列長度無限制。
#
# q.join()    # 等到隊列為空的時候,在執行別的操作
# q.qsize()   # 返回隊列的大小 (不可靠)
# q.empty()   # 當隊列為空的時候,返回True 否則返回False (不可靠)
# q.full()    # 當隊列滿的時候,返回True,否則返回False (不可靠)
# q.put(item, block=True, timeout=None) #  將item放入Queue尾部,item必須存在,可以參數block默認為True,表示當隊列滿時,會等待隊列給出可用位置,
# #                          為False時為非阻塞,此時如果隊列已滿,會引發queue.Full 異常。 可選參數timeout,表示 會阻塞設置的時間,過后,
# #                           如果隊列無法給出放入item的位置,則引發 queue.Full 異常
# q.get(block=True, timeout=None) #   移除并返回隊列頭部的一個值,可選參數block默認為True,表示獲取值的時候,如果隊列為空,則阻塞,為False時,不阻塞,
# #                       若此時隊列為空,則引發 queue.Empty異常。 可選參數timeout,表示會阻塞設置的時候,過后,如果隊列為空,則引發Empty異常。
# q.put_nowait(item) #   等效于 put(item,block=False)
# q.get_nowait() #    等效于 get(item,block=False)
message = queue.Queue(10)def producer(i):print("put:",i)# while True:
    message.put(i)def consumer(i):# while True:msg = message.get()print(msg)for i in range(12):t = threading.Thread(target=producer, args=(i,))t.start()for i in range(10):t = threading.Thread(target=consumer, args=(i,))t.start()
qs = message.qsize()
print("當前消息隊列的長度為:%d"%(qs))
print("當前消息隊列的長度為:",qs)
queue示例代碼

join()方法主線程等待,最多等待時間可以hi設置,eg:t.join(2)

    import threadingdef f0():passdef f1(a1,a2):time.sleep(10)f0()t = threading.Thread(target=f1,args(111,222,))t.setDaemon(True)  #默認false 主線程將等待執行完成后結束,設置為true后主線程將不在等待
    t.start()t = threading.Thread(target=f1,args(111,222,))t.start()t = threading.Thread(target=f1,args(111,222,))t.start()t = threading.Thread(target=f1,args(111,222,))t.start()
threading demo

5、進程 :multiprocess是py進程模塊

進程之間默認是隔離得,線程的資源默認是共享的

兩個進程共享數據需要使用特殊得對象: array:其他語音?或manager.dict()

進程不是,越多越好,建議使用線程池來控制。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from multiprocessing import Pool
import time
def myFun(i):time.sleep(2)return i+100def end_call(arg):print("end_call",arg)# print(p.map(myFun,range(10)))
if __name__ == "__main__":p = Pool(5)for i in range(10):p.apply_async(func=myFun,args=(i,),callback=end_call)print("end")p.close()p.join()
porcesspooldemo
#!/usr/bin/env python
# -*- coding:utf-8 -*-from multiprocessing import  Pool
import timedef f1(a):time.sleep(1)print(a)return 1000
def f2(arg):print(arg)if __name__ =="__main__":pool = Pool(5)for i in range(50):pool.apply_async(func=f1, args=(i,),callback=f2)# pool.apply(func=f1, args=(i,))print('<<=================>>')pool.close()pool.join()
processpooldemo2

6、線程池py沒有提供,我們需要自己編寫

簡單線程池示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import queue
import threading
import timeclass ThreadPool(object):def __init__(self, max_num=20):self.queue = queue.Queue(max_num)for i in range(max_num):self.queue.put(threading.Thread)def get_thread(self):return self.queue.get()def add_thread(self):self.queue.put(threading.Thread)def func(pool,a1):time.sleep(2)print(a1)pool.add_thread()p = ThreadPool(10)for i in range(100):#獲得類thread = p.get_thread()#對象 = 類()#
    t = thread(target=func,args=(p,i,))t.start()
"""
pool = ThreadPool(10)def func(arg, p):print argimport timetime.sleep(2)p.add_thread()for i in xrange(30):thread = pool.get_thread()t = thread(target=func, args=(i, pool))t.start()
"""# p = ThreadPool()
# ret = p.get_thread()
#
# t = ret(target=func,)
# t.start()
View Code

復雜的線城池示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-import queue
import threading
import contextlib
import timeStopEvent = object()class ThreadPool(object):def __init__(self, max_num, max_task_num = None):if max_task_num:self.q = queue.Queue(max_task_num)else:self.q = queue.Queue()# 多大容量self.max_num = max_numself.cancel = Falseself.terminal = False# 真實創建的線程列表self.generate_list = []# 空閑線程數量self.free_list = []def run(self, func, args, callback=None):"""線程池執行一個任務:param func: 任務函數:param args: 任務函數所需參數:param callback: 任務執行失敗或成功后執行的回調函數,回調函數有兩個參數1、任務函數執行狀態;2、任務函數返回值(默認為None,即:不執行回調函數):return: 如果線程池已經終止,則返回True否則None"""if self.cancel:returnif len(self.free_list) == 0 and len(self.generate_list) < self.max_num:self.generate_thread()w = (func, args, callback,)self.q.put(w)def generate_thread(self):"""創建一個線程"""t = threading.Thread(target=self.call)t.start()def call(self):"""循環去獲取任務函數并執行任務函數"""# 獲取當前進程current_thread = threading.currentThread()self.generate_list.append(current_thread)# 取任務event = self.q.get()while event != StopEvent:# 是元組=》是任務# 解開任務包# 執行任務
func, arguments, callback = eventtry:result = func(*arguments)success = Trueexcept Exception as e:success = Falseresult = Noneif callback is not None:try:callback(success, result)except Exception as e:passwith self.worker_state(self.free_list, current_thread):if self.terminal:event = StopEventelse:event = self.q.get()else:# 不是元組,不是任務# 標記:我空閑了# 執行后線程死掉
            self.generate_list.remove(current_thread)def close(self):"""執行完所有的任務后,所有線程停止"""self.cancel = Truefull_size = len(self.generate_list)while full_size:self.q.put(StopEvent)full_size -= 1def terminate(self):"""無論是否還有任務,終止線程"""self.terminal = Truewhile self.generate_list:self.q.put(StopEvent)self.q.empty()@contextlib.contextmanagerdef worker_state(self, state_list, worker_thread):"""用于記錄線程中正在等待的線程數"""state_list.append(worker_thread)try:yieldfinally:state_list.remove(worker_thread)# How to use
pool = ThreadPool(5)def callback(status, result):# status, execute action status# result, execute action return valuepassdef action(i):print(i)for i in range(30):#將任務放在隊列#著手開始處理任務#創建線程(有空閑線程則不創建;不高于線程池的限制;根據任務個數判斷)  =》線程去隊列中去任務ret = pool.run(action, (i,), callback)time.sleep(5)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
# pool.close()
# pool.terminate()
View Code

?7、上下文管理:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  queue
import  contextlib
"""
q = queue.Queue()
li = []# li.append(1)
# q.get()
# li.remove(1)@contextlib.contextmanager
def worker_stater(xxx,val):xxx.append(val)try:yield 123finally:xxx.remove(val)q.put("john")
with worker_stater(li,1) as f:print('before',li)print(f)q.get()passpassprint('after',li)
"""@contextlib.contextmanager
def myopen(file_path,mode):f = open(file_path,mode,encoding='utf-8')try:yield  ffinally:f.close()with myopen('index.html','r') as file_obj:print(file_obj.readline())
demo

8、協程:

協程主要應用在IO密集型場景,由程序來控制,也叫微線程,高性能通常與協程掛鉤

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  geventdef foo():print('Running in foo')gevent.sleep(0)  #切換協程print('Explicit context switch to foo agein')
def bar():print('Running in bar')gevent.sleep(0)  #切換協程print('Explicit context switch back to bar agein')gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),
])
demo1
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from gevent import  monkey;monkey.patch_all()
import  gevent
import  requestsdef f(url):print('GET:%s' % url)resp = requests.get(url)data = resp.textprint(url,len(data))gevent.joinall([gevent.spawn(f,'http://www.python.org/'),gevent.spawn(f,'https://www.yahoo.com/'),gevent.spawn(f,'https://github.com/'),
])
demo2
#!/usr/bin/env python
# -*- coding:utf-8 -*-from greenlet import  greenletdef test1():print(12)gr2.switch()print(34)gr2.switch()def test2():print(56)gr1.switch()print(78)gr1.switch()gr1 = greenlet(test1)
gr2 = greenlet(test2)gr1.switch()
demo3

?

end

轉載于:https://www.cnblogs.com/workherd/p/8809764.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452057.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452057.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452057.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php課程 8-28 php如何繪制生成顯示圖片

php課程 8-28 php如何繪制生成顯示圖片 一、總結 一句話總結&#xff1a;gd庫輕松解決 1、php圖片操作生成的圖的兩種去向是什么&#xff1f; 一種在頁面直接輸出&#xff0c;一種存進本地磁盤 2、php操作圖片的庫有哪些&#xff1f; PHP: Image Processing and Generation - M…

代碼行技術

用代碼行技術估算軟件規模時&#xff0c;當程序較小時常用的單位是代碼行數&#xff08;LOC&#xff09;&#xff0c;當程序較大時常用的單位是千行代碼數&#xff08;KLOC&#xff09;。 代碼行技術的主要優點是&#xff0c;代碼是所有軟件開發項目都有的“產品”&#xff0c;…

網絡爬蟲--8.編碼趣聞

很久很久以前&#xff0c;有一群人&#xff0c;他們決定用8個可以開合的晶體管來組合成不同的狀態&#xff0c;以表示世界上的萬物。他們看到8個開關狀態是好的&#xff0c;于是他們把這稱為"字節"。 再后來&#xff0c;他們又做了一些可以處理這些字節的機器&#…

科技領域的一分鐘

各位果迷是否能想象在一分鐘之內&#xff0c;科技領域都會發生什么事情&#xff1f;——蘋果平均每分鐘賣出81部 iPad&#xff1b;在 iPhone 4S 發布后的第一個周末&#xff0c;每分鐘賣出925部 iPhone 4S&#xff1b;RIM每分鐘賣出103臺黑莓手機&#xff1b;Amazon每分鐘賣出1…

flavr—超級漂亮的jQuery扁平彈出對話框

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 插件描述&#xff1a;flavr是一個時尚的扁平彈出對話框為您的下一個網站。 flavr是響應設計布局&#xff0c;能夠適應任何屏幕大小。 得…

經緯度之間的距離計算

來自谷歌地圖的計算公式&#xff1a; 通過JAVA的Math類各種方法調用。實現上述公式 private static double EARTH_RADIUS 6378.137;// 單位千米/*** 角度弧度計算公式 rad:(). <br/>* * 360度2π πMath.PI* * x度 x*π/360 弧度* * author chiwei* param d* return* s…

在CentOS7阿里云服務器部署ThinkPHP5,并配置phpstrom實現同步開發(微信小程序及管理員后端)...

小程序和后端同步開發 1.服務器安裝tp5框架&#xff1a; 方法很多比如&#xff1a;github、linux命令直接手動下、composer 都可以&#xff0c;方法很多&#xff0c;百度一下&#xff0c;不再累述 2.這時你會發現怎么都訪問出現不了這個令人舒心的界面&#xff08;ok第一個坑到…

ER圖( 實體聯系圖)

E-R圖也稱實體-聯系圖(Entity Relationship Diagram)&#xff0c;提供了表示實體類型、屬性和聯系的方法&#xff0c;用來描述現實世界的概念模型。 它是描述現實世界概念結構模型的有效方法。是表示概念模型的一種方式&#xff0c;用矩形表示實體型&#xff0c;矩形框內寫明…

網絡爬蟲--9.正則表達式

文章目錄一. 正則表達式1.為什么要學正則表達式2.什么是正則表達式3.正則表達式匹配規則二. Python 的 re 模塊1.re 模塊的一般使用步驟2.compile 函數3.match 方法4.search 方法5.findall 方法6.finditer 方法7.split 方法8.sub 方法9.匹配中文10.貪婪模式與非貪婪模式1&#…

概念模型

將需求分析得到的用戶需求抽象為信息結構&#xff08;即概念模型&#xff09;的過程就是概念結構設計 概念模型的特點 &#xff08;1&#xff09;能真實、充分地反映現實世界&#xff0c;是現實世界的一個真 實模型。 &#xff08;2&#xff09;易于理解&#xff0c;從…

筆記本電池的正確使用方法

一、新買筆記本不需要激活&#xff0c;也不需要前三次的充電12小時深充深放&#xff0c;這主要是鋰電池的原理和特性決定的。電池設計有電量保護&#xff0c;不可能將電量完全用完&#xff0c;當然也不可能過度充電。 二、筆記本電池的壽命受周圍環境的影響很大&#xff0c;最好…

關于XShell 啟動虛擬機的weblogic并在本地打開oracle-weblogic 有關部署

對于沒有用過這款軟件的童鞋&#xff0c;我想必定會有幾步彎路&#xff1a; 1.新建好的虛擬機記得換成root用戶【su root】~ifconfig【eth0 inet addr】如果沒有這項請點擊右上角的電腦標識&#xff0c;鼠標左擊一下連接&#xff0c;沒有了x號就重新輸入ifconfig就有了 2.xshe…

JQuery Datatables Dom 和 Language 參數詳細說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Dom說明 定義表格控件在頁面的顯示順序。 每個控件元素在數據表都有一個關聯的單個字母。 l - 每頁顯示行數的控件f - 檢索條件的控件…

程序員的思維修煉》讀書筆記

PB15061359 王亞正 這本書主要是從思維角度上來寫的&#xff0c;不具體針對到程序員如何寫代碼。我覺得這本書不僅僅適合程序員&#xff0c;其他對各行各業的人都同樣適用。 書中首先講了新手和專家的區別&#xff0c;一個需要靠規則&#xff0c;另一個則是靠感覺。 之后介紹了…

網絡爬蟲--10.使用正則表達式的爬蟲

文章目錄一. 前言二. 第一步&#xff1a;獲取數據三. 第二步&#xff1a;篩選數據四. 第三步&#xff1a;保存數據五. 第四步&#xff1a;實現循環抓取一. 前言 現在擁有了正則表達式這把神兵利器&#xff0c;我們就可以進行對爬取到的全部網頁源代碼進行篩選了。 下面我們一…

一對一 一對多 多對多

一對一 例如&#xff0c;學校里一個班級只有一個正班長&#xff0c;而一個班長只在一個班中任職&#xff0c;則班級與班長之間具有一對一聯系。 一對多 例如&#xff0c;一個班級中有若干名學生&#xff0c;而每個學生只在一個班級中學習&#xff0c;則班級與學生之間具有一…

Mac下的Jenkins安裝

安裝方式 1&#xff09;通過命令行安裝 brew install jenkins&#xff0c;可能會遇到先更新 brew 的情況 https://brew.sh/index_zh-cn&#xff1b; 2&#xff09;通過 pkg 安裝&#xff0c;官方網址&#xff1a;https://jenkins.io/ 安裝完成后&#xff0c;會自動打開瀏覽器…

Order By 排序條件中帶參數的寫法(Oracle數據庫、MyBatis)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 sortWay 是參數。 當sortWay 為 llpx 就 ORDER BY FORMAT ASC&#xff0c;為 btypx 就ORDER BY BID DESC &#xff0c;為 zhpx 就 ORDE…

拼湊代碼與編程

拼湊代碼與編程&#xff08;Hacking Vs. Programming&#xff09;之間有什么不同&#xff1f;我聽說過的一個觀點是駭客可以在短時間內編許多代碼&#xff0c;但是一旦發生變更&#xff0c;這些代碼就要完全重寫。而程序員也許會花更多的時間來編碼&#xff0c;但發生變化的時候…

實體間的聯系

&#xff08;1&#xff09;兩個實體型之間的聯系&#xff1a; ①一對一聯系&#xff08;1∶1&#xff09; ②一對多聯系&#xff08;1∶n&#xff09; ③多對多聯系&#xff08;m∶n&#xff09; &#xff08;2&#xff09;兩個以上的實體型之間的聯系&#xff1a; 一般地…