python基础____学习笔记10 (多线程)

一、多线程
每个进程至少都有一个线程,而这个线程就是我们通常说的主线程,创建的子线程共享主线程之间的数据,所有线程之间操作共享的数据就需要同步与互斥
1.1 创建线程
  导入线程模块

import threading

参数说明
Thread([group [, target [, name [, args [, kwargs]]]]])

  • group: 线程组,目前只能使用None
  • target: 执行的目标任务名
  • args: 以元组的方式给执行任务传参
  • kwargs: 以字典方式给执行任务传参
  • name: 线程名,一般不用设置
import threading
import time

# 带有参数的任务
def task(name, count):
    for i in range(count):
        print(f"{name}任务执行中..")
        time.sleep(0.2)
    else:
        print(f"{name}任务执行完成")

if __name__ == '__main__':
    # 创建子进程
    # args: 以元组的方式给任务传入参数
    sub_thread1 = threading.Thread(target=task, args=('xiaoming', 5))
    sub_thread2 = threading.Thread(target=task, kwargs={'name': 'xiaozhang', 'count': 5})
    sub_thread1.start()
    sub_thread2.start()
    sub_thread1.join()
    sub_thread2.join()

1.2 继承方式创建线程

from threading import Thread
import time
import os


class MyThread(Thread):

    def __init__(self, name, count):
        Thread.__init__(self)
        self.name = name
        self.count = count

    def run(self):
        for i in range(self.count):
            print(f"{self.name}任务执行中..")
            time.sleep(0.2)
        else:
            print(f"{self.name}任务执行完成")


if __name__ == '__main__':
    # 创建子进程
    # args: 以元组的方式给任务传入参数
    sub_thread1 = MyThread('xiaoming', 5)
    sub_thread2 = MyThread('xiaozhang', 5)
    sub_thread1.start()
    sub_thread2.start()

    sub_thread1.join()
    sub_thread2.join()
    print('主线程结束')

线程创建和继承创建多么的相似,不同之处在于线程是共享数据,进程是拷贝数据

1.3 互斥锁
线程之间访问共享资源,需要加互斥锁,避免出现同时访问共享资源的时候,出现问题
互斥锁:

lock = threading.Lock()

lock.acquire()
#共享资源
lock.release()

或者使用上下文
with lock:
    #共享资源

实例:

import threading
import time
lock = threading.Lock()
num = 0
def incre(count):
    global num
    while count > 0:
        with lock:
            num += 1
        count -= 1
        time.sleep(0.1)

def main():
    threads = []
    for i in range(5):
        thread = threading.Thread(target=incre, args=(100,))
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()
    print("expected value is", 5 * 100, "real value is", num)


if __name__ == '__main__':
    main()
  • 互斥锁的作用就是保证同一时刻只能有一个线程去操作共享数据,保证共享数据不会出现错误问题
  • 使用互斥锁会影响代码的执行效率,但避免同时访问数据出现问题 
  • 互斥锁如果没有使用好容易出现死锁的情况

1.4 线程安全的队列


Queue 模块实现了线程安全的队列,尤其适合多线程编程, 是最简单也是最常用的队列
Queue Queue : 一个先进先出( FIFO )的队列,最先加入队列的元素最先取出;
LifoQueue LifoQueue : 一个后进先出( LIFO )的队列,最后加入队列的元素最先取出;
PriorityQueue PriorityQueue :优先级队列,队列中的元素根据优先级排序 。

Queue:

import threading
import time
import random

from queue import Queue


class Producer(threading.Thread):
    """
    Producer thread 制作线程
    """
    def __init__(self, t_name, myqu):  # 传入线程名、实例化队列
        threading.Thread.__init__(self, name=t_name)  # t_name即是threadName
        self.data = myqu

    def run(self):
        for i in range(5):  # 生成0-4五条队列
            print("%s: %s is producing %d to the queue!" % (time.ctime(), self.getName(), i))  # 当前时间t生成编号d并加入队列
            self.data.put(i)  # 写入队列编号
            time.sleep(random.randint(1,10) / 5)  # 随机休息一会
        #print("%s: %s producing finished!" % (time.ctime(), self.getName))  # 编号d队列完成制作

class Consumer(threading.Thread):
    def __init__(self, t_name, myqu):
        threading.Thread.__init__(self, name=t_name)
        self.data = myqu
    def run(self):
        for i in range(5):
            val = self.data.get()
            print("%s: %s is consuming. %d in the queue is consumed!" % (\
            time.ctime(), self.getName(), val))  # 编号d队列已经被消费
            time.sleep(random.randint(1,10))
        #print("%s: %s consuming finished!" % (time.ctime(), self.getName()))  # 编号d队列完成消费

if __name__ == '__main__':
    myqueue= Queue()
    productThread = Producer('ProducerThread', myqueue)
    comsumerThread = Consumer('comsumerThread', myqueue)
    productThread.start()
    comsumerThread.start()
    productThread.join()
    comsumerThread.join()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值