多线程应用

1、程序、进程、线程

程序与进程

程序
  • 静态的代码
  • 程序运行后至少能创建一个进程
进程
  • 执行起来的代码
  • 程序的执行实例、动态的
  • 进程占用内存资源
  • 1个进程至少包含1个线程

进程与线程

进程
  • 1个进程至少包含1个线程,即主线程
  • 同时也是可以创建多个子线程
  • 进程之间的内存空间是独立的,数据是独立的
线程
  • 程序执行流的最少单元
  • 是CPU的可执行上下文
  • 同一个进程中的线程共享同一内存空间,数据共享
  • 线程数据的安全性需要保护

多线程

在单个程序中同时运行多个线程完成不同的被划分成一块一块的工作,称为多线程

2、python多线程模块

多线程编程创建方式

第一种 继承Thread

import threading

# 第一种 继承Thread

class MyThred(threading.Thread):   # 继承父类
    def __init__(self, thread_name):
        super(MyThred, self).__init__(name=thread_name)     # 调用父类,构造一个自定义构造函数的写法

    def run(self):
        print("%s 在执行中..." %self.name)


for i in range(10):       # 创造10个线程将其运行起来
    MyThred("testThread" + str(i)).start()

在这里插入图片描述

第二种 (推荐使用)

import threading

def show(num):   # 定义一个函数
    print('当前线程: %s 在执行...' % num)


for i in range(10):
    t = threading.Thread(target=show, args=(i,))   # 定义一个线程,直接实例化Thread这个实例,target执行的目标,args是运行参数,元组只有一个元素加逗号加以区分
    t.start()

在这里插入图片描述

第三种


import threading
import time

def dowaiting():   # 子线程调用dowaiting让它等一会
    print('子线程开始等待...')
    time.sleep(3)  # 让其等待3秒
    print('子线程等待结束')


# 主线程
print('主线程开始执行')
t = threading.Thread(target=dowaiting)
t.start()

print('主线程的其他操作')

t.join()               # 让子线程合并到主线程里来,也就是让主线程等待子线程执行结束
print('主线程结束')

3、守护线程

import threading
import time

def dowaiting():   # 子线程调用dowaiting让它等一会
    print(threading.current_thread().getName() + '子线程开始等待...')  # 可知当前线程是谁
    time.sleep(3)  # 让其等待3秒
    print(threading.current_thread().getName() + '子线程等待结束')


# 主线程
print('主线程开始执行')
for i in range(3):      # 创建了3个线程
    t = threading.Thread(target=dowaiting)
    t.setDaemon(True)   # 主线程守护进程
    t.start()

print('主线程结束')

在这里插入图片描述

4、线程安全


# 线程安全

import threading
import time

number = 0

# 1 : 1000
# 2 : 2000
# 1 : 2120
# 2 : 3456

def add():
    global number
    for _ in range(1000000):
        number += 1
    print('子线程 %s 执行结束后:number = %d' % (threading.current_thread().getName(), number))

for i in range(2):
    t = threading.Thread(target=add)
    t.start()
    t.join()

time.sleep(3)
print('主线程结束.number = '+str(number))

在这里插入图片描述

5、线程安全与线程锁

  • 互斥锁Lock :只能被一个进程所访问
  • RLock可重入锁 :可以有多把锁锁在一个对象上
  • 信号Semaphore
  • 事件Event
  • 条件Condition
  • Barrier “阻碍”

加互斥锁Lock

import threading
import time
number = 0
lock = threading.Lock()  # 定义锁


def add(lk):   # 传入锁
    global number
    # 加锁
    lk.acquire()
    for _ in range(1000000):
        number += 1
    print('子线程 %s 执行结束后:number = %d' % (threading.current_thread().getName(), number))
    # 解锁
    lk.release()
    

for i in range(2):
    t = threading.Thread(target=add, args=(lock, ))
    t.start()

time.sleep(3)
print('主线程结束.number = '+str(number))

在这里插入图片描述

也可以用with语句加锁,为了防止文件、资源未关闭,锁未释放等问题

import threading
import time
number = 0
lock = threading.Lock()  # 定义锁


def add(lk):   # 传入锁
    global number
    # 加锁
    with lk:
        for _ in range(1000000):
            number += 1
        print('子线程 %s 执行结束后:number = %d' % (threading.current_thread().getName(), number))
        # 解锁


for i in range(2):
    t = threading.Thread(target=add, args=(lock, ))
    t.start()

time.sleep(3)
print('主线程结束.number = '+str(number))

在这里插入图片描述

6、生产者与消费者

在这里插入图片描述
多线程的环境配上消息队列,一种模式,解决效率很低的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值