python中的多线程

  1. 当python程序执行时会默认创建一个主线程,除了主线程之外我们还可以创建别的线程,可以使用threading引入:
import threading
import time

def thinking():
    for i in range(3):
        # threading.current_thread()查看当前正在运行的线程的名字
        print(str(threading.current_thread())+'am thinking')
        time.sleep(1)

def drawing():
    for i in range(3):
        print(str(threading.current_thread())+'am drawing')
        time.sleep(1)

def main():
    t1 = threading.Thread(target=thinking)
    t2 = threading.Thread(target=drawing)
    # 开始执行线程
    t1.start()
    t2.start()
    # 查看当前的线程的数量
    print(threading.enumerate())

main()
  1. 如何使用类的方法引入多线程
  • 必须将多线程代码写在run方法中
import threading
import time


class ThinkingThread(threading.Thread):
    def run(self):
        for i in range(3):
            # threading.current_thread()查看当前正在运行的线程的名字
            print(str(threading.current_thread()) + 'am thinking')
            time.sleep(1)


class DrawingThread(threading.Thread):
    def run(self):
        for i in range(3):
            print(str(threading.current_thread()) + 'am drawing')
            time.sleep(1)


def main():
    t1 = ThinkingThread()
    t2 = DrawingThread()
    t1.start()
    t2.start()


main()
  1. 在多线程共享访问全局变量时,会出现读脏数据的情况,需要引入锁机制:threading.Lock()
  • 未引入锁机制
import threading
VALUE = 0

def add_value():
    global VALUE
    for i in range(100000):
        VALUE += 1
    print(VALUE)
    
def main():
    for i in range(2):
        t = threading.Thread(target=add_value)
        t.start()
     
main()
输出:
100000
153852
  • 引入锁机制
import threading

VALUE = 0
lock = threading.Lock()

def add_value():
    global VALUE
    lock.acquire()
    for i in range(100000):
        VALUE += 1
    lock.release()
    print(VALUE)


def main():
    for i in range(2):
        t = threading.Thread(target=add_value)
        t.start()


main()
输出:
100000
200000
  1. threading.Condition()类似threading.Lock,可以修改全局数据的时候进行上锁,也可以修改完毕后进行解锁,下列是常用的函数:
  • acquire:上锁
  • release:解锁
  • wait:将当前的进程除了等待状态,并且会释放锁,可以被其他线程使用notify和notify_all函数唤醒
  • notify:通知某个正在等待的线程,默认第1个等待的线程
  • notify_all:通知所有正在等待的线程。notify和notify_all不会释放锁。并且需要在release之前调用。
  • 用threading.Condition()实现生产者和消费者问题:
import threading
import random
import time

ALL_MONEY = 1000
conditon_lock = threading.Condition()
TIMES = 0


class Producer(threading.Thread):
    def run(self):
        global ALL_MONEY
        global TIMES
        while True:
            TIMES = TIMES + 1
            conditon_lock.acquire()
            if TIMES > 10:
                break
            money = random.randint(1, 1000)
            ALL_MONEY = ALL_MONEY + money
            print('{}生产了{}元,还剩于{}元'.format(threading.current_thread(), money, ALL_MONEY))
            conditon_lock.notify_all()
            conditon_lock.release()
            time.sleep(1)


class Consumer(threading.Thread):
    def run(self):
        global ALL_MONEY
        global TIMES
        while True:
            money = random.randint(1, 1000)
            conditon_lock.acquire()
            while ALL_MONEY < money:
                if TIMES >= 10:
                    conditon_lock.release()
                    return
                conditon_lock.wait()
            ALL_MONEY = ALL_MONEY-money
            print('{}消费了{}元,还剩于{}元'.format(threading.current_thread(), money, ALL_MONEY))
            conditon_lock.release()


def main():
    for i in range(5):
        t = Producer(name="生产者{}".format(i))
        t.start()
    for i in range(3):
        t = Consumer(name="消费者{}".format(i))
        t.start()


main()
  1. Queue线程安全队列
    这些队列都实现了锁原语,能够在多线程直接使用,可以使用队列来实现线程间的同步,创建一个先进先出队列:
  • 初始化Queue(maxsize)
  • qsize():返回队列的大小
  • empty():判断队列是否为空
  • full():判读队列是否满了
  • get():取出队头元素
  • put():讲一个数据放到队列中
导入:
from queue import Queue
q = Queue(4)
  1. GIL全局解释器锁
  • Python自带的解释器是CPython。CPython解释器的多线程实际上是一个假的多线程(在多核cpu中,只能利用一核,不能利用多核)。同一时刻只有一个线程在执行,为了保证同一时刻只有一个线程在执行,在CPython解释器中有一个东西叫做GIL,全局解释器。
  • GIL虽然是一个假的多线程,但是在处理一些IO操作(比如文件读写和网络请求)还是在很大程序上提高效率的。在IO操作上建议使用多线程提高效率。在一些CPU计算密级进程不建议使用多线程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值