多線程_詳

多線程

什麼是線程:

​ 線程不會複製主線程的空間,而是在進程內部劃分一個區域,線程間能夠共享資源( 會影響全局變量 ),局部變量不共享php

進程與線程的區別:

進程裏至少有一個線程,線程不會建立新的空間;進程會複製主進程的全部文件,開闢新的內存空間,佔資源。python

​ 進程 每增長一個進程就會建立一分內存空間 修改全局變量不會有影響 通訊麻煩c#

​ 例:兒子一出生就和老子分家,並搬出去 ,進程間資源互不影響,進程間通訊須要使用隊列來傳遞。安全

​ 線程 共享內存空間 修改全局變量會影響 線程安全 互斥鎖ruby

例: 兒子一出生就和老子放假了,不過是合租。客廳( 全局 )相互公用,臥室(局部)私有。多線程

瞭解線程:

demo:

# demo
import time
# 導入包
import threading


def sing(num):
    print('我在唱歌:{}次'.format(num))
    # 睡1秒
    time.sleep(1)


for i in range(10):
    # 建立線程
    t = threading.Thread(target=sing, args=(i,))
    # 開啓線程
    t.start()
    # sing(i)

線程的全局變量,是不安全的,須要使用互斥鎖來進行鎖定狀態(似: MySQL中的事務)ui

​ 示例:線程

import threading

num = 0


def add():
    # 修改全局變量
    global num
    # 開啓互斥鎖
    lock.acquire()
    for i in range(100000):
        num += 1
    print(f'add:{num}')
    # 關閉互斥鎖
    lock.release()


def read():
    #  修改全局變量
    global num
    # 開啓互斥鎖
    lock.acquire()
    for i in range(100000):
        num += 1
    print(f'read:{num}')
    # 關閉互斥鎖
    lock.release()


# 建立一個鎖對象(只須要建立一個)
lock = threading.Lock()
# 建立一個線程
t = threading.Thread(target=add)
# 開啓線程
t.start()

# 建立一個線程
t = threading.Thread(target=read)
# 開啓線程
t.start()

運行結果:調試

若是不使用互斥鎖進行鎖定,當數值較小的時候可能沒有太大的變化,若是大了,必有問題( 運算錯誤 )code

Thread的繼承方式

import threading


class MyThread(threading.Thread):
    # 初始化
    def __init__(self, name):
        #  繼承類必需要繼續初始化
        super(MyThread, self).__init__()
        self.name = name

    def run(self):  # run 是固定的
        print(f'傳入的參數是:{self.name}')


def main():
    #     實例對象
    myThread = MyThread('張三')
    # 開啓
    myThread.start()


if __name__ == '__main__':
    main()

繼承必需要初始化繼承類

繼承類方式裏面 的run方法是固定的,不可變!

互斥鎖

互斥鎖也是在threading類上,使用方法

# 建立一個鎖對象(只須要建立一個)
lock = threading.Lock()

互斥鎖:

​ 遵循: 原子性,惟一性

通俗的講: 互斥鎖是一個狀態,當狀態( 鎖定 )開啓時,其餘的動做將不能進行操做,當解除( 解鎖 )狀態時,其餘的能夠接管繼續操做.[ 主要用於線程安全 ]

死鎖的解決方案:

​ 解決:添加超時時間

加鎖越多,效率越慢

線程 的同步(流程執行)

案例:

import threading, time


def p1():
    # 上鎖
    while True:
        if lock1.acquire():
            print('1')
            time.sleep(1)
            #     執行完成時將p2解鎖
            lock2.release()


def p2():
    while True:
        if lock2.acquire():
            print('2')
            time.sleep(1)
            # p2執行完成時解鎖p3
            lock3.release()


def p3():
    while True:
        if lock3.acquire():
            print('3')
            time.sleep(1)
            # p3執行完成時解鎖p1
            lock1.release()


# 建立線程
t1 = threading.Thread(target=p1)
t2 = threading.Thread(target=p2)
t3 = threading.Thread(target=p3)

# 建立鎖
lock1 = threading.Lock()
lock2 = threading.Lock()
lock3 = threading.Lock()
# 將p2鎖住
lock2.acquire()
# 將p3鎖住
lock3.acquire()

# 開啓線程
t1.start()
t2.start()
t3.start()

特定環境需求,同步下不講效率

進程:獨立內存空間 資源分配的單元

線程:共享內存空間 大大減小內存的使用 線程不安全 調試單元 最後作事情的那我的

一個程序運行至少一個進程,至少一個線程

何時使用多進程,何時時候使用多線程?

IO密集型:多線程 input output

CPU密集型:多進程

編譯型:c go c#

解釋型:python php ruby perl js

GIL: 全局解釋鎖 不是PYthon特徵 cpython( 解釋器 ) 多線程的時候,爲了保證線程自己安全,加了這個全局解釋鎖,

在同一時間點,只能有一個線程去CPU上執行

C語言

相關文章
相關標籤/搜索