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 变量

在这里插入图片描述
在这里插入图片描述

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