2021/5/27爬虫第十七次课(资源竞争、互斥锁、死锁、线程队列)

本文详细讲解了如何使用Python的threading模块进行线程管理,包括查看线程数量、理解线程间的资源竞争,特别是通过互斥锁解决数据同步问题以及死锁的防范。实例演示了多线程中共享变量和使用锁的场景,以及队列Queue在并发中的应用。

一、查看线程数量

threading.enumerate()#Return a list of all Thread objects currently alive
#以列表形式返回存在的线程对象

实操:

import threading
import time

def demo1():
    for i in range(5):
        print('demo1--%d'%i)
        time.sleep(1)


def demo2():
    for i in range(10):
        print('demo2--%d' % i)
        time.sleep(1)


def main():
    t1 = threading.Thread(target=demo1,name='demo1')
    t2 = threading.Thread(target=demo2,name='demo2')
    t1.start()
    t2.start()
    while True:
        print(threading.enumerate())
        if len(threading.enumerate()) <= 1:
            break
        time.sleep(1)
if __name__ == '__main__':
    main()

二、线程间的资源竞争

引入:一个线程写入,一个线程读取,没问题,如果两个线程都写入呢?

2.1线程间的通信

(多线程共享全局变量)

2.2互斥锁和死锁

2.2.1互斥锁

当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制

某个线程要更改共享数据时,先将其锁定,此时资源的状态为"锁定",其他线程不能改变,只到该线程释放资源,将资源的状态变成"非锁定",其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

创建锁
mutex = threading.Lock()

锁定
mutex.acquire()

解锁
mutex.release()

2.2.2死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。

(就好像在现实社会中,男女双方在闹别扭之后,都在等待对方先道歉。
如果双方都这样固执地等待对方先开口,弄不好,就 over 了。)

python多线程之死锁现象与递归锁

资源竞争现象:

import threading
import time

# 创建一个线程锁 
lock = threading.Lock() # 不可重复的锁 只能上一次
# lock = threading.RLock()# # 可上重复的锁 
num = 0

def demo1(nums):
    global num
    # 上锁
    # lock.acquire()
    lock.acquire()
    for i in range(nums): # 100 0 - 99  100
        num += 1
    # 解锁
    # lock.release()
    lock.release()
    print('demo1-num-%d' % num)

def demo2(nums):
    global num
    lock.acquire()
    for i in range(nums):
        num += 1
    lock.release()
    print('demo1-num-%d' % num)


def main():
    t1 = threading.Thread(target=demo1,args=(1000000,))
    t2 = threading.Thread(target=demo2,args=(1000000,))
    t1.start()
    # time.sleep(0.3)
    # t1.join()
    t2.start()
    # t2.join()
    time.sleep(2)
    print('main-num-%d' % num)


if __name__ == '__main__':
    main()

三、线程队列Queue

  • 队列的特点 先进先出
empty() 判断队列是否为空
full() 判断队列是否满了
get() 从队列当中取出数据
put() 将一个数据添加到队列当中
from queue import Queue

q = Queue(3)

# print(q.empty()) # True代表是空的  False 代表队列不是空的
# print(q.full()) # False代表不是满的 True 代表队列满了

q.put(1)
q.put(2)
q.put(3)
# print('='*80)
#
# print(q.empty())
# print(q.full())
# q.put(4,timeout=2)
# q.put_nowait(4)
print(q.get())
print(q.get())
print(q.get())
# print(q.get())
基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于NSGA-III算法的微电网多目标优化调度展开研究,重点介绍了如何利用该先进多目标进化算法解决微电网系统中多个相互冲突的目标(如运行成本最小化、碳排放最低、供电可靠性最高等)的协同优化问题。文中结合Matlab代码实现,详细阐述了NSGA-III算法的基本原理、在微电网调度模型中的建模过程、约束条件处理、目标函数设计以及仿真结果分析,展示了其相较于传统优化方法在求解高维、非线性、多目标问题上的优越性。同时,文档还提供了丰富的相关研究案例和技术支持背景,涵盖电力系统优化、智能算法应用及Matlab仿真等多个方面。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源优化领域的工程技术人员;尤其适合正在进行微电网调度、多目标优化算法研究或撰写相关论文的研究者。; 使用场景及目标:①掌握NSGA-III算法的核心思想及其在复杂能源系统优化中的应用方式;②学习如何构建微电网多目标调度模型并利用Matlab进行仿真求解;③为科研项目、毕业论文或实际工程提供算法实现参考和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码实例,逐步调试运行并深入理解算法流程与模型构建细节,同时可参考文档中列出的其他优化案例进行横向对比学习,以提升综合应用能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笔记本IT

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值