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

歡迎訪問 生活随笔!

生活随笔

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

python

python程序多线程_Python-多线程编程

發布時間:2025/4/5 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python程序多线程_Python-多线程编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

threading模塊

threading 模塊的對象

對 象描 述

Thread

表示一個執行線程的對象

Lock

鎖原語對象(和 thread 模塊中的鎖一樣)

RLock

可重入鎖對象,使單一線程可以(再次)獲得已持有的鎖(遞歸鎖)

Condition

條件變量對象,使得一個線程等待另一個線程滿足特定的“條件”,比如改變狀態或 某個數據值

Event

條件變量的通用版本,任意數量的線程等待某個事件的發生,在該事件發生后所有 線程將被激活

Semaphore

為線程間共享的有限資源提供了一個“計數器”,如果沒有可用資源時會被阻塞

BoundedSemaphore

與 Semaphore 相似,不過它不允許超過初始值

Timer

與 Thread 相似,不過它要在運行前等待一段時間

Barrier①

創建一個“障礙”,必須達到指定數量的線程后才可以繼續

守護線程

thread模塊,不支持守護線程這個概念。

當主線程退出時,所有子線程都將終止,不管它們是否仍在工作

如果你不希望發生這種行為,就要引入守護線程的概念了

threading 模塊支持守護線程,其工作方式是:守護線程一般是一個等待客戶端請求服務的服務器。

如果沒有客戶端請求,守護線程就是空閑的。

如果把一個線程設置為守護線程,就表示這個線程是不重要的,進程退出時不需要等待這個線程執行完成。

要將一個線程設置為守護線程,需要在啟動線程之前執行如下賦值語句:thread.daemon = True

同樣,要檢查線程的守護狀態,也只需要檢查這個值即可,一個新的子線程會繼承父線程的守護標記。

整個 Python 程序(主線程)將在所有非守護線程退出之后才退出

換句話說,就是沒有剩下存活的非守護線程時。

Thread 類

threading 模塊的 Thread 類是主要的執行對象。它有 thread 模塊中沒有的很多函數。

Thread

對象的屬性和方法

屬 性描 述

Thread 對象數據屬性

name

線程名

ident

線程的標識符

daemon

布爾標志,表示這個線程是否是守護線程

Thread 對象方法

init(group=None, tatget=None, name=None, args=(), kwargs ={}, verbose=None, daemon=None) ③

實例化一個線程對象,需要有一個可調用的 target,以及其參數 args 或 kwargs。還可以傳遞 name 或 group 參數,不過后者還未實現。此 外 , verbose 標 志 也 是 可 接 受 的。 而 daemon 的 值 將 會 設定 thread.daemon 屬性/標志

屬 性描 述

start()

開始執行該線程

run()

定義線程功能的方法(通常在子類中被應用開發者重寫)

join (timeout=None)

直至啟動的線程終止之前一直掛起;除非給出了 timeout(秒),否則 會一直阻塞

getName()①

返回線程名

setName (name)①

設定線程名

isAlivel /is_alive ()②

布爾標志,表示這個線程是否還存活

isDaemon()③

如果是守護線程,則返回 True;否則,返回 False

setDaemon(daemonic)③

把線程的守護標志設定為布爾值 daemonic(必須在線程 start()之前 調用)

創建實例

啟動一個線程就是把一個函數傳入并創建Thread實例,然后調用start()開始執行

#!/usr/bin/env python

#-*- coding:utf8 -*-import threading

import time

def loop():

strat_time=time.time()

print('thread %s is running...' %threading.current_thread().name) #當前進程名

n= 0

while n < 5:

n= n + 1print('thread %s >>> %s' %(threading.current_thread().name, n))

time.sleep(1)

print('thread %s ended.' %threading.current_thread().name)

end_time=time.time()

all_time= end_time -strat_time

print("共用時:%s" %all_time)

print('thread %s is running...time = %s' %(threading.current_thread().name,time.ctime()))

t= threading.Thread(target=loop, name='LoopThread') # 創建Thread實例

t.start() # 開始執行

t.join() # 阻塞主線程

print('thread %s ended. time = %s' % (threading.current_thread().name,time.ctime()))

多線程和多進程最大的不同在于,多進程中,同一個變量,各自有一份拷貝存在于每個進程中,互不影響,Lock

而多線程中,所有變量都由所有線程共享,所以,任何一個變量都可以被任何一個線程修改,

因此,線程之間共享數據最大的危險在于多個線程同時改一個變量,把內容給改亂了。

一個用Lock解決的示例代碼

import time, threading

# 假定這是你的銀行存款:

balance= 0

lock=threading.Lock() #創建鎖

def change_it(n):

# 先存后取,結果應該為0:globalbalance

balance= balance +n

balance= balance -n

def run_thread(n):for i in range(100000):lock.acquire() # 申請鎖try:

change_it(n)finally:lock.release() # 釋放鎖

t1= threading.Thread(target=run_thread, args=(5,))

t2= threading.Thread(target=run_thread, args=(8,))

t1.start()

t2.start()

t1.join()

t2.join()

print("The Res is %d" % balance)

queue模塊,提供線程間通信的機制,從而讓線程之間可以互相分享數據生產者-消費者問題和queue模塊

具體而言,就是創建一個隊列,讓生產者(線程)在其中放入新的商品,而消費者(線程)消費這些商品

queue

模塊常用屬性

屬 性描 述

queue 模塊的類

Queue(maxsize=0)

創建一個先入先出隊列。如果給定最大值,則在隊列沒有空間時阻塞;否則(沒 有指定最大值),為無限隊列

LifoQueue(maxsize=0)

創建一個后入先出隊列。如果給定最大值,則在隊列沒有空間時阻塞;否則(沒 有指定最大值),為無限隊列

PriorityQueue(maxsize=0)

創建一個優先級隊列。如果給定最大值,則在隊列沒有空間時阻塞,否則(沒 有指定最大值) ,為無限隊列

Queue/queue 異常

Empty

當對空隊列調用 get*()方法時拋出異常

Full

當對已滿的隊列調用 put*()方法時拋出異常

Queue/queue 對象方法

qsize ()

返回隊列大小(由于返回時隊列大小可能被其他線程修改,所以該值為近似值)

empty()

如果隊列為空,則返回 True;否則,返回 False

full()

如果隊列已滿,則返回 True;否則,返回 False

put (item, block=Ture, timeout=None)

將 item 放入隊列。如果 block 為 True(默認)且 timeout 為 None,則在有可用 空間之前阻塞;如果 timeout 為正值,則最多阻塞 timeout 秒;如果 block 為 False, 則拋出 Empty 異常

put_nowait(item)

和 put(item, False)相同

get (block=True, timeout=None)

從隊列中取得元素。如果給定了 block(非 0),則一直阻塞到有可用的元素 為止

get_nowait()

和 get(False)相同

task_done()

用于表示隊列中的某個元素已執行完成,該方法會被下面的 join()使用

join()

在隊列中所有元素執行完畢并調用上面的 task_done()信號之前,保持阻塞

MyThread.py

#!/usr/bin/env python

import threadingfromtime import ctimeclassMyThread(threading.Thread):

def __init__(self, func, args, name=''):

threading.Thread.__init__(self)

self.func=func

self.name=name

self.args=args

def run(self):

print('開始執行', self.name, '在:', ctime())

self.res= self.func(*self.args)

print(self.name,'結束于:', ctime())

def getResult(self):return self.res

product.py

#!/usr/bin/env python

#-*- coding:utf8 -*-

fromrandom import randintfromtime import sleepfromqueue import QueuefromMyThread import MyThread

# 將一個對象放入隊列中

def writeQ(queue):

print('正在為隊列生產………')

queue.put('商品', 1)

print('當前商品總數:', queue.qsize())

# 消費隊列中的一個對象

def readQ(queue):

val= queue.get(1)

print('正在從隊列中消費商品……消費后還剩余商品:', queue.qsize())

# 模仿生產者。

def writer(queue, loops):for i inrange(loops):

writeQ(queue)

sleep(randint(1, 3)) # writer的睡眠時間一般比reader短,是為了阻礙 reader從空隊列中獲取對象,換句話說就是使得輪到reader執行時,已存在可消費對象的可能性更大。

# 模仿消費者

def reader(queue, loops):for i inrange(loops):

readQ(queue)

sleep(randint(2, 5))

funcs=[writer, reader]

nfuncs=range(len(funcs))

def main():

nloops= randint(2, 5) # randint 和randrange類似,區別在于,randrange是半開半閉區間,而randint是閉區間

q= Queue(32)

threads=[] # 模擬線程池for i innfuncs:

t=MyThread(funcs[i], (q, nloops), funcs[i].__name__) # 創建線程

threads.append(t)for i innfuncs:

threads[i].start() # 開始執行線程for i innfuncs:

threads[i].join()

print('結束')if __name__ == '__main__':

main()

總結

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

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