国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

python多線程

J4ck_Chan / 3279人閱讀

摘要:對于操作為主的編程來說,多進(jìn)程和多先產(chǎn)出的性能差別不大,甚至多線程比多進(jìn)程的性能還高,因?yàn)槎嗑€程編程更加輕量級。

GIL

global interpreter lock(cpython)

同一時(shí)刻只有一個(gè)線程運(yùn)行在一個(gè)cpu上執(zhí)行字節(jié)碼(無法將多個(gè)線程映射到多個(gè)cpu上)

import dis

def add(a):
    a = a + 1
    return a

print(dis.dis(add))
GIL在某些情況下會釋放

每次的結(jié)果都不一樣 線程之間的安全問題

GIL會根據(jù)執(zhí)行的直接碼行數(shù)或者時(shí)間片釋放GIL

遇到IO操作時(shí)主動釋放

total = 0

def add():
    #1. dosomething1
    #2. io操作
    # 1. dosomething3
    global total
    for i in range(1000000):
        total += 1
def desc():
    global total
    for i in range(1000000):
        total -= 1

import threading
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()

thread1.join()
thread2.join()
print(total)
多線程編程

操作系統(tǒng)能夠調(diào)度的的最小單位是進(jìn)程,因?yàn)檫M(jìn)程對系統(tǒng)的資源消耗非常大,所以后期就演變成了線程,線程實(shí)際上是依賴于我們的進(jìn)程(任務(wù)管理器中我們實(shí)際上能看到的其實(shí)是進(jìn)程 ),操作系統(tǒng)能調(diào)度的最小單元是線程。

對于io操作為主的編程來說,多進(jìn)程和多先產(chǎn)出的性能差別不大,甚至多線程比多進(jìn)程的性能還高,因?yàn)槎嗑€程編程更加輕量級。

簡單的線程
import time
from threading import Thread


def get_detail_html(url):
    print("get detail html started")
    time.sleep(2)
    print("get detail html end")


def get_detail_url(url):
    print("get detail url started")
    time.sleep(4)
    print("get detail url end")


if __name__ == "__main__":
    thread1 = Thread(target=get_detail_html, args=("",))
    thread2 = Thread(target=get_detail_url, args=("",))
    # 設(shè)置為守護(hù)線程 當(dāng)主線程運(yùn)行完時(shí) 子線程被kill掉
    thread1.setDaemon(True)
    thread2.setDaemon(True)
    start_time = time.time()
    thread1.start()
    thread2.start()

    # 設(shè)置為阻塞 等待線程運(yùn)行完再關(guān)閉主線程
    thread1.join()
    thread2.join()
    # 默認(rèn)情況下 主線程退出與時(shí) 子線程不會被kill掉
    print("last time: {}".format(time.time() - start_time))
重載線程實(shí)現(xiàn)多線程
import time
import threading

def get_detail_html(url):
    print("get detail html started")
    time.sleep(2)
    print("get detail html end")


def get_detail_url(url):
    print("get detail url started")
    time.sleep(4)
    print("get detail url end")


#2. 通過集成Thread來實(shí)現(xiàn)多線程
class GetDetailHtml(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)

    def run(self):
        print("get detail html started")
        time.sleep(2)
        print("get detail html end")


class GetDetailUrl(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)

    def run(self):
        print("get detail url started")
        time.sleep(4)
        print("get detail url end")

if  __name__ == "__main__":
    thread1 = GetDetailHtml("get_detail_html")
    thread2 = GetDetailUrl("get_detail_url")
    start_time = time.time()
    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    #當(dāng)主線程退出的時(shí)候, 子線程kill掉
    print ("last time: {}".format(time.time()-start_time))
多線程之間的通信

使用queue

# filename: thread_queue_test.py
# 通過queue的方式進(jìn)行線程間同步
from queue import Queue
import time
import threading


def get_detail_html(queue):
    # 死循環(huán) 爬取文章詳情頁
    while True:
        url = queue.get()
        # for url in detail_url_list:
        print("get detail html started")
        time.sleep(2)
        print("get detail html end")


def get_detail_url(queue):
    # 死循環(huán) 爬取文章列表頁
    while True:
        print("get detail url started")
        time.sleep(4)
        for i in range(20):
            # put 等到有空閑位置 再放入
            # put_nowait 非阻塞方式
            queue.put("http://projectsedu.com/{id}".format(id=i))
        print("get detail url end")


# 1. 線程通信方式- 共享變量
if __name__ == "__main__":
    detail_url_queue = Queue(maxsize=1000)

    thread_detail_url = threading.Thread(target=get_detail_url, args=(detail_url_queue,))
    for i in range(10):
        html_thread = threading.Thread(target=get_detail_html, args=(detail_url_queue,))
        html_thread.start()

    start_time = time.time()
    # 調(diào)用task_down從主線程退出
    detail_url_queue.task_done()
    # 從queue的角度阻塞
    detail_url_queue.join()

    print("last time: {}".format(time.time() - start_time))
線程的同步問題

在多線程編程中必須要面對的問題

無鎖不安全的原因
# 沒有鎖
def add1(a):
    a += 1

def desc1(a):
    a -= 1

"""add
1. load a  a = 0
2. load 1  1
3. +    1
4. 賦值給a a=1
"""

"""add
1. load a  a = 0
2. load 1  1
3. -    1
4. 賦值給a a=-1
"""
import dis
print(dis.dis(add1))
print(dis.dis(desc1))
普通鎖(Lock)

用鎖會影響性能,鎖會引起死鎖(兩次獲取鎖,獲取鎖之后不釋放,互相等待(a需要b的資源 b需要a的資源))

import threading
from threading import Lock

total = 0
# 定義一把鎖
lock = Lock()
def add():
    global total
    global lock
    for i in range(1000000):
        # 獲取鎖
        lock.acquire()
        total += 1
        # 釋放鎖
        lock.release()

def desc():
    global total
    for i in range(1000000):
        lock.acquire()
        total -= 1
        lock.release()

thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()

thread1.join()
thread2.join()
print(total)
相互等待(資源競爭)
"""
A(a、b)
acquire (a)
acquire (b)

B(a、b)
acquire (b)
acquire (a)

# 解決辦法
B(a、b)
acquire (a)
acquire (b)
"""
可重入鎖(Rlock)
import threading
from threading import RLock

total = 0
# 可重入鎖 可以在同一個(gè)線程中可載入多次
lock = RLock()
def add(lock):
    global total
    for i in range(1000000):
        # 獲取鎖
        lock.acquire()
        lock.acquire()
        total += 1
        do_something(lock)
        # 釋放鎖
        lock.release()
        lock.release()

def desc():
    global total
    for i in range(1000000):
        lock.acquire()
        total -= 1
        lock.release()

def do_something(lock):
    lock.acquire()
    # do something
    lock.release()

thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()

thread1.join()
thread2.join()
print(total)
條件變量鎖(condition)

用于復(fù)雜的線程間同步

# 沒有條件鎖 不能實(shí)現(xiàn)對話
import threading


class XiaoAi(threading.Thread):
   def __init__(self, lock):
       super().__init__(name="小愛")
       self.lock = lock

   def run(self):
       self.lock.acquire()
       print("{} : 在 ".format(self.name))
       self.lock.release()

       self.lock.acquire()
       print("{} : 好啊 ".format(self.name))
       self.lock.release()


class TianMao(threading.Thread):
   def __init__(self, lock):
       super().__init__(name="天貓精靈")
       self.lock = lock

   def run(self):
       self.lock.acquire()
       print("{} : 小愛同學(xué) ".format(self.name))
       self.lock.release()

       self.lock.acquire()
       print("{} : 我們來對古詩吧 ".format(self.name))
       self.lock.release()


if __name__ == "__main__":
   cond = threading.Condition()
   xiaoai = XiaoAi(cond)
   tianmao = TianMao(cond)

   xiaoai.start()
   tianmao.start()
# 條件鎖
import threading


class XiaoAi(threading.Thread):
    def __init__(self, cond):
        super().__init__(name="小愛")
        self.cond = cond

    def run(self):
        with self.cond:
            self.cond.wait()
            print("{} : 在 ".format(self.name))
            self.cond.notify()

            self.cond.wait()
            print("{} : 好啊 ".format(self.name))
            self.cond.notify()

            self.cond.wait()
            print("{} : 君住長江尾 ".format(self.name))
            self.cond.notify()

            self.cond.wait()
            print("{} : 共飲長江水 ".format(self.name))
            self.cond.notify()

            self.cond.wait()
            print("{} : 此恨何時(shí)已 ".format(self.name))
            self.cond.notify()

            self.cond.wait()
            print("{} : 定不負(fù)相思意 ".format(self.name))
            self.cond.notify()

class TianMao(threading.Thread):
    def __init__(self, cond):
        super().__init__(name="天貓精靈")
        self.cond = cond

    def run(self):
        with self.cond:
            print("{} : 小愛同學(xué) ".format(self.name))
            self.cond.notify()
            self.cond.wait()

            print("{} : 我們來對古詩吧 ".format(self.name))
            self.cond.notify()
            self.cond.wait()

            print("{} : 我住長江頭 ".format(self.name))
            self.cond.notify()
            self.cond.wait()

            print("{} : 日日思君不見君 ".format(self.name))
            self.cond.notify()
            self.cond.wait()

            print("{} : 此水幾時(shí)休 ".format(self.name))
            self.cond.notify()
            self.cond.wait()

            print("{} : 只愿君心似我心 ".format(self.name))
            self.cond.notify()
            self.cond.wait()



if __name__ == "__main__":
    from concurrent import futures
    cond = threading.Condition()
    xiaoai = XiaoAi(cond)
    tianmao = TianMao(cond)

    # 啟動順序很重要
    # 在調(diào)用with cond之后才能調(diào)用wait或者notify方法
    # condition有兩層鎖, 一把底層鎖會在線程調(diào)用了wait方法的時(shí)候釋放,
    # 上面的鎖會在每次調(diào)用wait的時(shí)候分配一把并放入到cond的等待隊(duì)列中,
    # 等到notify方法的喚醒
    xiaoai.start()
    tianmao.start()

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42970.html

相關(guān)文章

  • 淺談Python線程

    摘要:進(jìn)程可創(chuàng)建多個(gè)線程來執(zhí)行同一程序的不同部分。就緒等待線程調(diào)度。運(yùn)行線程正常運(yùn)行阻塞暫停運(yùn)行,解除阻塞后進(jìn)入狀態(tài)重新等待調(diào)度。消亡線程方法執(zhí)行完畢返回或者異常終止。多線程多的情況下,依次執(zhí)行各線程的方法,前頭一個(gè)結(jié)束了才能執(zhí)行后面一個(gè)。 淺談Python多線程 作者簡介: 姓名:黃志成(小黃)博客: 博客 線程 一.什么是線程? 操作系統(tǒng)原理相關(guān)的書,基本都會提到一句很經(jīng)典的話: 進(jìn)程...

    zsirfs 評論0 收藏0
  • Python線程

    摘要:多線程的理解多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。多線程創(chuàng)建在中,同樣可以實(shí)現(xiàn)多線程,有兩個(gè)標(biāo)準(zhǔn)模塊和,不過我們主要使用更高級的模塊。多線程的應(yīng)用場景。 1、多線程的理解 多進(jìn)程和多線程都可以執(zhí)行多個(gè)任務(wù),線程是進(jìn)程的一部分。線程的特點(diǎn)是線程之間可以共享內(nèi)存和變量,資源消耗少(不過在Unix環(huán)境中,多進(jìn)程和多線程資源調(diào)度消耗差距不明顯,Unix調(diào)度較快),缺點(diǎn)是線程之間...

    dcr309duan 評論0 收藏0
  • 如何編寫快速且線程安全的Python代碼

    摘要:其次,解釋器的主循環(huán),一個(gè)名為的函數(shù),讀取字節(jié)碼并逐個(gè)執(zhí)行其中的指令。所有線程都運(yùn)行相同的代碼,并以相同的方式定期從它們獲取鎖定。無論如何,其他線程無法并行運(yùn)行。 概述 如今我也是使用Python寫代碼好多年了,但是我卻很少關(guān)心GIL的內(nèi)部機(jī)制,導(dǎo)致在寫Python多線程程序的時(shí)候。今天我們就來看看CPython的源代碼,探索一下GIL的源碼,了解為什么Python里要存在這個(gè)GIL,...

    B0B0 評論0 收藏0
  • Python線程專題縱覽篇

    摘要:上一篇文章進(jìn)程專題完結(jié)篇多進(jìn)程處理的一般建議下一篇文章線程專題多線程使用的必要性進(jìn)程線程進(jìn)程能夠完成多任務(wù),比如在一個(gè)電腦上可以運(yùn)行多個(gè)軟件。由于占用資源少,也使得多線程程序并發(fā)比較高。 上一篇文章:Python進(jìn)程專題完結(jié)篇:多進(jìn)程處理的一般建議下一篇文章:Python線程專題1:多線程使用的必要性 進(jìn)程VS線程 進(jìn)程:能夠完成多任務(wù),比如在一個(gè)電腦上可以運(yùn)行多個(gè)軟件。線程:也能夠...

    張紅新 評論0 收藏0
  • python學(xué)習(xí)筆記- 線程

    摘要:也提供多線程支持,而且中的線程并非是模擬出來的多線程,而是系統(tǒng)級別的標(biāo)準(zhǔn)庫提供了兩個(gè)模塊和。同一個(gè)變量,線程則會互相共享。例如多個(gè)線程對銀行中的某一個(gè)賬戶進(jìn)行操作。但是實(shí)際情況是隨意切換線程。說到的多線程編程,就會繞不過。 該文章參考了http://www.liaoxuefeng.com/wi... 廖雪峰的教程。 一個(gè)進(jìn)程至少有一個(gè)線程。Python也提供多線程支持,而且Python...

    RiverLi 評論0 收藏0
  • # Python 線程和鎖

    摘要:多線程和鎖作者博客進(jìn)程和線程進(jìn)程是執(zhí)行中的計(jì)算機(jī)程序。線程包括開始執(zhí)行順序和結(jié)束三部分。的多進(jìn)程相關(guān)模塊模塊是高級別的多線程模塊。線程鎖當(dāng)多線程爭奪鎖時(shí),允許第一個(gè)獲得鎖的線程進(jìn)入臨街區(qū),并執(zhí)行代碼。 Python 多線程和鎖 作者博客:http://zzir.cn/ 進(jìn)程和線程 進(jìn)程是執(zhí)行中的計(jì)算機(jī)程序。每個(gè)進(jìn)程都擁有自己的地址空間、內(nèi)存、數(shù)據(jù)棧及其它的輔助數(shù)據(jù)。操作系統(tǒng)管理著所有的...

    cpupro 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<