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

歡迎訪問 生活随笔!

生活随笔

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

python

python_day9线程、进程和协程

發布時間:2025/6/15 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python_day9线程、进程和协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python線程

Threading用于提供線程相關的操作,線程是應用程序中工作的最小單元。

#!/usr/bin/env?python #?-*-?coding:utf-8?-*- import?threading import?timedef?show(arg):time.sleep(1)print?'thread'+str(arg)for?i?in?range(10):t?=?threading.Thread(target=show,?args=(i,))t.start()print?'main?thread?stop'

上述代碼創建了10個“前臺”線程,然后控制器就交給了CPU,CPU根據指定算法進行調度,分片執行指令。

更多方法:

  • start ? ? ? ? ? ?線程準備就緒,等待CPU調度

  • setName ? ? ?為線程設置名稱

  • getName ? ? ?獲取線程名稱

  • setDaemon ? 設置為后臺線程或前臺線程(默認)
    ? ? ? ? ? ? ? ? ? ?如果是后臺線程,主線程執行過程中,后臺線程也在進行,主線程執行完畢后,后臺線程不論成功與否,均停止
    ? ? ? ? ? ? ? ? ? ??如果是前臺線程,主線程執行過程中,前臺線程也在進行,主線程執行完畢后,等待前臺線程也執行完成后,程序停止

  • join ? ? ? ? ? ? ?逐個執行每個線程,執行完畢后繼續往下執行,該方法使得多線程變得無意義

  • run ? ? ? ? ? ? ?線程被cpu調度后自動執行線程對象的run方法

#??自定義線程類import?threading import?timeclass?MyThread(threading.Thread):def?__init__(self,num):threading.Thread.__init__(self)self.num?=?numdef?run(self):#定義每個線程要運行的函數print("running?on?number:%s"?%self.num)time.sleep(3)if?__name__?==?'__main__':t1?=?MyThread(1)t2?=?MyThread(2)t1.start()t2.start()

線程鎖(Lock、RLock)

由于線程之間是進行隨機調度,并且每個線程可能只執行n條執行之后,當多個線程同時修改同一條數據時可能會出現臟數據,所以,出現了線程鎖 - 同一時刻允許一個線程執行操作。

#??未使用鎖#!/usr/bin/env?python #?-*-?coding:utf-8?-*- import?threading import?timegl_num?=?0def?show(arg):global?gl_numtime.sleep(1)gl_num?+=1print?gl_numfor?i?in?range(10):t?=?threading.Thread(target=show,?args=(i,))t.start()print?'main?thread?stop'#!/usr/bin/env?python #coding:utf-8import?threading import?timegl_num?=?0lock?=?threading.RLock()def?Func():lock.acquire()global?gl_numgl_num?+=1time.sleep(1)print?gl_numlock.release()for?i?in?range(10):t?=?threading.Thread(target=Func)t.start()

信號量(Semaphore)

互斥鎖 同時只允許一個線程更改數據,而Semaphore是同時允許一定數量的線程更改數據 ,比如廁所有3個坑,那最多只允許3個人上廁所,后面的人只能等里面有人出來了才能再進去。

import?threading,timedef?run(n):semaphore.acquire()time.sleep(1)print("run?the?thread:?%s"?%n)semaphore.release()if?__name__?==?'__main__':num=?0semaphore??=?threading.BoundedSemaphore(5)?#最多允許5個線程同時運行for?i?in?range(20):t?=?threading.Thread(target=run,args=(i,))t.start()

事件(event)

python線程的事件用于主線程控制其他線程的執行,事件主要提供了三個方法?set、wait、clear。

事件處理的機制:全局定義了一個“Flag”,如果“Flag”值為 False,那么當程序執行 event.wait 方法時就會阻塞,如果“Flag”值為True,那么event.wait 方法時便不再阻塞。

  • clear:將“Flag”設置為False

  • set:將“Flag”設置為True

#!/usr/bin/env?python #?-*-?coding:utf-8?-*-import?threadingdef?do(event):print?'start'event.wait()print?'execute'event_obj?=?threading.Event() for?i?in?range(10):t?=?threading.Thread(target=do,?args=(event_obj,))t.start()event_obj.clear() inp?=?raw_input('input:') if?inp?==?'true':event_obj.set()

條件(Condition)

使得線程等待,只有滿足某條件時,才釋放n個線程

import?threadingdef?run(n):con.acquire()con.wait()print("run?the?thread:?%s"?%n)con.release()if?__name__?==?'__main__':con?=?threading.Condition()for?i?in?range(10):t?=?threading.Thread(target=run,?args=(i,))t.start()while?True:inp?=?input('>>>')if?inp?==?'q':breakcon.acquire()con.notify(int(inp))con.release()def?condition_func():ret?=?Falseinp?=?input('>>>')if?inp?==?'1':ret?=?Truereturn?retdef?run(n):con.acquire()con.wait_for(condition_func)print("run?the?thread:?%s"?%n)con.release()if?__name__?==?'__main__':con?=?threading.Condition()for?i?in?range(10):t?=?threading.Thread(target=run,?args=(i,))t.start()

Timer

定時器,指定n秒后執行某操作

from?threading?import?Timerdef?hello():print("hello,?world")t?=?Timer(1,?hello) t.start()??#?after?1?seconds,?"hello,?world"?will?be?printed

Python 進程

from?multiprocessing?import?Process import?threading import?timedef?foo(i):print?'say?hi',ifor?i?in?range(10):p?=?Process(target=foo,args=(i,))p.start()

注意:由于進程之間的數據需要各自持有一份,所以創建進程需要的非常大的開銷。

進程數據共享

進程各自持有一份數據,默認無法共享數據

#??進程間默認無法數據共享#!/usr/bin/env?python #coding:utf-8from?multiprocessing?import?Process from?multiprocessing?import?Managerimport?timeli?=?[]def?foo(i):li.append(i)print?'say?hi',lifor?i?in?range(10):p?=?Process(target=foo,args=(i,))p.start()print?'ending',li#方法一,Array from?multiprocessing?import?Process,Array temp?=?Array('i',?[11,22,33,44])def?Foo(i):temp[i]?=?100+ifor?item?in?temp:print?i,'----->',itemfor?i?in?range(2):p?=?Process(target=Foo,args=(i,))p.start()#方法二:manage.dict()共享數據 from?multiprocessing?import?Process,Managermanage?=?Manager() dic?=?manage.dict()def?Foo(i):dic[i]?=?100+iprint?dic.values()for?i?in?range(2):p?=?Process(target=Foo,args=(i,))p.start()p.join()#??類型對應表'c':?ctypes.c_char,??'u':?ctypes.c_wchar, 'b':?ctypes.c_byte,??'B':?ctypes.c_ubyte, 'h':?ctypes.c_short,?'H':?ctypes.c_ushort, 'i':?ctypes.c_int,???'I':?ctypes.c_uint, 'l':?ctypes.c_long,??'L':?ctypes.c_ulong, 'f':?ctypes.c_float,?'d':?ctypes.c_doublefrom?multiprocessing?import?Process,?Queuedef?f(i,q):print(i,q.get())if?__name__?==?'__main__':q?=?Queue()q.put("h1")q.put("h2")q.put("h3")for?i?in?range(10):p?=?Process(target=f,?args=(i,q,))p.start()

當創建進程時(非使用時),共享數據會被拿到子進程中,當進程中執行完畢后,再賦值給原值。

#??進程鎖實例#!/usr/bin/env?python #?-*-?coding:utf-8?-*-from?multiprocessing?import?Process,?Array,?RLockdef?Foo(lock,temp,i):"""將第0個數加100"""lock.acquire()temp[0]?=?100+ifor?item?in?temp:print?i,'----->',itemlock.release()lock?=?RLock() temp?=?Array('i',?[11,?22,?33,?44])for?i?in?range(20):p?=?Process(target=Foo,args=(lock,temp,i,))p.start()

進程池

進程池內部維護一個進程序列,當使用時,則去進程池中獲取一個進程,如果進程池序列中沒有可供使用的進進程,那么程序就會等待,直到進程池中有可用進程為止。

進程池中有兩個方法:

  • apply

  • apply_async

#!/usr/bin/env?python #?-*-?coding:utf-8?-*- from??multiprocessing?import?Process,Pool import?timedef?Foo(i):time.sleep(2)return?i+100def?Bar(arg):print?argpool?=?Pool(5) #print?pool.apply(Foo,(1,)) #print?pool.apply_async(func?=Foo,?args=(1,)).get()for?i?in?range(10):pool.apply_async(func=Foo,?args=(i,),callback=Bar)print?'end' pool.close() pool.join()#進程池中進程執行完畢后再關閉,如果注釋,那么程序直接關閉。

協程

線程和進程的操作是由程序觸發系統接口,最后的執行者是系統;協程的操作則是程序員。

協程存在的意義:對于多線程應用,CPU通過切片的方式來切換線程間的執行,線程切換時需要耗時(保存狀態,下次繼續)。協程,則只使用一個線程,在一個線程中規定某個代碼塊執行順序。

協程的適用場景:當程序中存在大量不需要CPU的操作時(IO),適用于協程;

greenlet

#!/usr/bin/env?python #?-*-?coding:utf-8?-*-from?greenlet?import?greenletdef?test1():print?12gr2.switch()print?34gr2.switch()def?test2():print?56gr1.switch()print?78gr1?=?greenlet(test1) gr2?=?greenlet(test2) gr1.switch()

gevent

import?geventdef?foo():print('Running?in?foo')gevent.sleep(0)print('Explicit?context?switch?to?foo?again')def?bar():print('Explicit?context?to?bar')gevent.sleep(0)print('Implicit?context?switch?back?to?bar')gevent.joinall([gevent.spawn(foo),gevent.spawn(bar), ])

遇到IO操作自動切換:

from?gevent?import?monkey;?monkey.patch_all()??#?自己體會這句話的作用 import?gevent import?urllib2def?f(url):print('GET:?%s'?%?url)resp?=?urllib2.urlopen(url)data?=?resp.read()print('%d?bytes?received?from?%s.'?%?(len(data),?url))gevent.joinall([gevent.spawn(f,?'https://www.python.org/'),gevent.spawn(f,?'https://www.yahoo.com/'),gevent.spawn(f,?'https://github.com/'), ])


轉載于:https://blog.51cto.com/cuzihate/1861266

總結

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

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