python threading模塊

1、線程的介紹

在這裏插入圖片描述

2、線程與進程的區別

在這裏插入圖片描述
例子。

    import threading
    import time
    
    
    def fun(num):
        print("線程執行%d"%num)
        time.sleep(2)
    
    # 執行5個形參
    for i in range(5):
        t = threading.Thread(target=fun, args=(i+1,))  # 設置線程
        t.start()     # 啓動線程

3、 查看幫助信息及參數信息

    import threading
    print(help(threading.Thread))

4、 查看當前形參數量

# coding=utf-8
import threading
from time import sleep, ctime


def sing():
    for i in range(3):
        print("傻不傻%d" % i)
        sleep(1)

def dance():
    for i in range(3):
        print("????%d" % i)
        sleep(1)


if __name__ == '__main__':
    print('___開始___%s' % ctime())  # 獲取當前時間,字符串表示沒,讀格式
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    while True:
        length = len(threading.enumerate())
        print("當前運行的線程數爲:%d" % length)
        if length<=1:   # 等於就只剩一個主線程,說明副線程都運行完了
            break
        sleep(0.5)

5、子類化線程類

在這裏插入圖片描述

# coding=utf-8
import threading
import time


class MyThread(threading.Thread):
    def __init__(self, num, str1):
        super().__init__()
        self.num = num
        self.str1 = str1
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I am " + self.name + " @" + str(i) + " num:" + str(self.num) + "str1:" + self.str1  # name屬性中報錯的是當前線程的
            print(msg)


if __name__ == '__main__':
    t = MyThread(10, "abc")
    t.start()

6、線程的幾種狀態

在這裏插入圖片描述

7、線程共享全局變量

# coding=utf8
from threading import Thread
import time

g_num = 100


def work1():
    global g_num
    for i in range(3):
        g_num += 1
        print("---in work1.g_num is %d---" % g_num)


def work2():
    global g_num
    print("---in work2.g_num is %d---" % g_num)

print("----創建線程之前g_num is %d---" % g_num)
t1 = Thread(target=work1())
t1.start()
# 延遲一會,保證線程中的事情做完
t2 = Thread(target=work2())
t2.start()

8、用傳參的方式使用全局變量

例子一;全局變量爲不可變對象

# coding=utf8
from threading import Thread
import time

g_num = 100


def work1(num):
    for i in range(3):
        num += 1
        print("---in work1.g_num is %d---" % num)


def work2(num):
    print("---in work2.g_num is %d---" % num)

print("----創建線程之前g_num is %d---" % g_num)
t1 = Thread(target=work1, args=(g_num,))
t1.start()
# 延遲一會,保證線程中的事情做完
t2 = Thread(target=work2, args=(g_num,))
t2.start()
print("----創建線程之後g_num is %d---" % g_num)

輸出:

----創建線程之前g_num is 100---
---in work1.g_num is 101---
---in work1.g_num is 102---
---in work1.g_num is 103---
---in work2.g_num is 100---
----創建線程之後g_num is 100---

第二個例子:全局變量爲可變對象

# coding=utf8
from threading import Thread
import time

g_num = [11, 22, 33]


def work1(num):
    for i in range(3):
        num.append(44)
        print("---in work1.g_num is %s---" % num)


def work2(num):
    print("---in work2.g_num is %s---" % num)


print("----創建線程之前g_num is %s---" % g_num)
t1 = Thread(target=work1, args=(g_num,))
t1.start()
# 延遲一會,保證線程中的事情做完
t2 = Thread(target=work2, args=(g_num,))
t2.start()
print("----創建線程之後g_num is %s---" % g_num)

輸出

----創建線程之前g_num is [11, 22, 33]---
---in work1.g_num is [11, 22, 33, 44]---
---in work1.g_num is [11, 22, 33, 44, 44]---
---in work1.g_num is [11, 22, 33, 44, 44, 44]---
---in work2.g_num is [11, 22, 33, 44, 44, 44]---
----創建線程之後g_num is [11, 22, 33, 44, 44, 44]---

9、線程同步問題

例子1

coding=utf8

import threading
import time

g_num = 0


def work1():
    global g_num
    for i in range(10):
       g_num += 1


for i in range(2):
    t = threading.Thread(target=work1)
    t.start()
print("----創建線程之後g_num is %s---" % g_num)

輸出

----創建線程之後g_num is 20---

例子2
把上面代碼中的 for i in range(10):改成 for i in range(1000000):
輸出

----創建線程之後g_num is 219002---

按理說應該輸出2000000,但是結果不是,這是因爲2個線程之間
進程在運行的時候,數據是放在內存裏的,而CPU在運算的時候,數據是要讀在數據的寄存器裏的(CPU中有很多寄存器),然後再在寄存器中對數據進行操作,最後再寫會內存裏。

在上面代碼中
在這裏插入圖片描述

10、線程同步-給線程加鎖

在這裏插入圖片描述
創建鎖

mutex = threading.Lock()

鎖定

mutex.acquire([blocking])

如果沒有設定block爲True,則當前線程會堵塞,直到獲取這個鎖爲止(如果沒有指定,默認爲True)
如果設定blocking爲False,則當前線程不會堵塞

釋放
mutex.relesse()

例子:加了一個互斥鎖,成功輸出結果

# coding=utf8
import threading
import time


class Task1(threading.Thread):
    def run(self):
        while True:
            if lock1.acquire():
                print("---Task1---")
                time.sleep(1)
                lock2.release()


class Task2(threading.Thread):
    def run(self):
        while True:
            if lock2.acquire():
                print("---Task2---")
                time.sleep(1)
                lock3.release()


class Task3(threading.Thread):
    def run(self):
        while True:
            if lock3.acquire():
                print("---Task3---")
                time.sleep(3)
                lock1.release()


lock1 = threading.Lock()
lock2 = threading.Lock()
lock2.acquire()
lock3 = threading.Lock()
lock3.acquire()

t1 = Task1()
t2 = Task2()
t3 = Task3()
t1.start()
t2.start()
t3.start()

通過3把鎖固定線程執行的順序,執行完線程t1,然後執行線程t2,然後執行線程t3,然後依次循環。

12、queue的使用

在這裏插入圖片描述

# coding=utf8

import threading

import time
from queue import Queue


class Producter(threading.Thread):
    def run(self):
        while True:
            if queue.qsize() < 1000:
                for x in range(100):
                    msg = "產品" + str(x)
                    print("%s創建了%s"%(self.name,  msg))
                    queue.put(msg)
                time.sleep(1)

class Consumer(threading.Thread):
    def run(self):
        while True:
            if queue.qsize() > 100:
                for x in range(3):
                    msg = queue.get()
                    print("%s消費了%s"%(self.name, msg))
                time.sleep(0.5)


queue = Queue()
for i in range(500):
    msg = "產品" + str(i)
    queue.put("msg")

for i in range(2):
    t = Producter()
    t.start()

for i in range(5):
    c = Consumer()
    c.start()

13、ThreadLocal 變量

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章