# 任何语言都会发生多线程,会出现不同步的问题,同步锁、死锁、递归锁
# 异步: 多任务, 多个任务之间执行没有先后顺序,可以同时运行,执行的先后顺序不会有什么影响,存在的多条运行主线
# 同步: 多任务, 多个任务之间执行的时候要求有先后顺序,必须一个先执行完成之后,另一个才能继续执行, 只有一个主线
# 阻塞:从调用者的角度出发,如果在调用的时候,被卡住,不能再继续向下运行,需要等待,就说是阻塞
# 非阻塞: 从调用者的角度出发, 如果在调用的时候,没有被卡住,能够继续向下运行,无需等待,就说是非阻塞
# def add():
# num = 1
# for i in range(100000000):
# num += i
# print(num)
# def mul():
# sum2 = 1
# for i in range(1,100000):
# sum2 *=i
# print(sum2)
# import threading,time
# start = time.time()
# t1 = threading.Thread(target=add)
# t2 = threading.Thread(target=mul)
# l = []
# l.append(t1)
# l.append(t2)
# for t in l:
# t.start()
# for t in l:
# t.join()
# print('Cost time %s'%(time.time()-start))
####################################################################################################################
# GIL:全局解释锁,python内置解释器中定义的,在同一个时刻,只能有一个线程被cpu执行
# 任务类型分为:1.IO密集型;2.计算密集型
# 对于IO密集型(使用多数):python可以使用多线程效率高,也可以采用多线程+协程
# 对于计算密集型:python的多线程就没有用了,由于cpython内置解释器的设计问题,充分保证了进程安全,不能同时处理计算进程
####################################################################################################################
#——————————————————————同步锁————————————————————————————————#
# import threading,time
# def sub():
# global num
# #——————————————————————————————#
# lock.acquire()#锁定,锁定后变成了串行
# temp = num
# time.sleep(0.02)
# num = temp-1
# lock.release()#解锁,释放资源
# # ——————————————————————————————#
# num = 100
# start = time.time()
# l = []
# lock = threading.Lock()
# for i in range(100):
# t = threading.Thread(target=sub)
# t.start()
# l.append(t)
# for i in l:
# t.join()
# print(num,time.time()-start)
#——————————————————————同步锁————————————————————————————————#
#————————————————————线程死锁和递归锁—————————————————————————————#
# 在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,
# 就会造成死锁,因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去
# RLock 递归锁,内部维护了一个计数器,acquire和release需要共同出现
# 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,
# 因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
# 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
# 解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
# 这个RLock内部维护着一个Lock和一个counter变量,
# counter记录了acquire的次数,从而使得资源可以被多次require。
# 直到一个线程所有的acquire都被release,其他的线程才能获得资源。
# 上面的例子如果使用RLock代替Lock,则不会发生死锁:
# import threading,time
# class MyThread(threading.Thread):
# def actionA(self):
# r_lock.acquire()
# print(self.name,'getA',time.ctime())
# time.sleep(1)
# r_lock.acquire()
# print(self.name, 'getB', time.ctime())
# time.sleep(1)
# r_lock.release()
# r_lock.release()
# def actionB(self):
# r_lock.acquire()
# print(self.name, 'getB', time.ctime())
# time.sleep(1)
# r_lock.acquire()
# print(self.name, 'getA', time.ctime())
# time.sleep(1)
# r_lock.release()
# r_lock.release()
# def run(self):
# self.actionA()
# time.sleep(0.5)
# self.actionB()
#
#
#
# if __name__ == '__main__':
# r_lock = threading.RLock()
# A = threading.Lock()
# B = threading.Lock()
# L = []
# for i in range(5):
# t = MyThread()
# t.start()
# L.append(t)
# for i in L:
# i.join()
# print('ending....')
####################################################################################################################
# 同步条件(Event)
# 同进程的一样
# 线程的一个关键特性是每个线程都是独立运行且状态不可预测。
# 如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,
# 这时线程同步问题就会变得非常棘手。
# 为了解决这些问题,我们需要使用threading库中的Event对象。
# 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。
# 在初始情况下,Event对象中的信号标志被设置为假。
# 如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。
# 一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。
# 如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行
# event.isSet():返回event的状态值;
# event.wait():如果 event.isSet()==False将阻塞线程;
# event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
# event.clear():恢复event的状态值为False。
####################################################################################################################
# 信号量:同时允许开启的线程个数
# 同进程的一样
# Semaphore管理一个内置的计数器,
# 每当调用acquire()时内置计数器-1;
# 调用release() 时内置计数器+1;
# 计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
# 实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为5):
####################################################################################################################
# 队列:队列是一种数据结构,列表是不安全的数据结构,多线程利器
# 队列的三种模式,先进先出,先进后出,按优先级进行
# 默认模式是先进先出
# import queue,time #线程队列
# q = queue.Queue()
# q.put(12)
# q.put('asd')
# q.put(14)
# q.put({'name':'panda'})
# while 1:
# data = q.get()
# print(data)
# time.sleep(1)
# print('-----')
# ####################################################################################################################
# 生产者消费者模型
# 为什么要使用生产者和消费者模式
# 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。
# 在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,
# 那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,
# 如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
#
# 什么是生产者消费者模式
#
# 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。
# 生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,
# 所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,
# 消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
# 这就像,在餐厅,厨师做好菜,不需要直接和客户交流,而是交给前台,
# 而客户去饭菜也不需要不找厨师,直接去前台领取即可,这也是一个结耦的过程。
# import time,random
# import queue,threading
# q = queue.Queue()
# def Producer(name):
# count = 0
# while count <10:
# print('正在制作')
# time.sleep(random.randrange(3))
# q.put(count)
# print('%s厨师%s号做好了一盘菜'%(name,count))
# count +=1
# print('做完了')
# def Consumer(name):
# count = 0
# while count <10:
# time.sleep(random.randrange(4))
# if not q.empty():
# data = q.get()
# print(data)
# print('\033[32;1m大胃王 %s 吃掉了 %s 一盘菜...\033[0m' % (name, data))
# else:
# print("-----吃的太快啦----")
# count += 1
# p1 = threading.Thread(target=Producer, args=('A',))
# c1 = threading.Thread(target=Consumer, args=('B',))
# p1.start()
# c1.start()

Pyhton学习——Day34的更多相关文章

  1. Pyhton学习——Day26

    #多态:多态指的是一类事物有多种形态# import abc# class Animal(metaclass = abc.ABCMeta):# 同一类事物:动物# @abc.abstractclass ...

  2. pyhton 学习

    官方学习文档 https://docs.python.org/3/tutorial/

  3. 20190320_head first pyhton学习笔记之构建发布

    1.把代码nester.py放入文件夹nester中,在文件夹中再新建一个setup.py文件,文件内容如下: from distutils.core import setup setup( name ...

  4. Pyhton学习——Day2

    Python开发IDE(工具)Pycharm.eclipse1.循环while 条件 #循环体 #条件为真则执行 #条件为假则执行break用于退出所有循环continue用于退出当前循环 2.Pyc ...

  5. Pyhton学习——Day28

    #上下文协议:文件操作时使用with执行# with open('a.txt','w',encoding='utf-8') as f1:# with语句,为了让一个对象兼容with语句,必须在这个对象 ...

  6. Pyhton学习——Day27

    # hasattr(obj,'name')-->obj.name# getattr(obj,'name',default = 'xxx')--->obj.name# setattr(obj ...

  7. Pyhton学习——Day25

    #面向对象的几个方法#1.静态方法@staticmethod,不能访问类属性,也不能访问实例属性,只是类的工具包#2.类方法:@classmethod,在函数属性前加上类方法,显示为(cls)代表类, ...

  8. Pyhton学习——Day24

    # #面向对象设计:# def dog(name,gender,type):# def jiao(dog):# print('One Dog[%s],wfwfwf'%dog['name'])# def ...

  9. Pyhton学习——Day23

    #re模块方法:findall search#findall:返回所有满足匹配条件的数值,放在列表里#search : #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象 ...

随机推荐

  1. day28 re(正则)模块

    目录 re模块有什么用? re模块的基础使用 元字符 终极 贪婪模式 非贪婪模式 re模块高级 comple match和search re.split() sub和subn 分组 re模块有什么用? ...

  2. c++ 优先级队列(priority_queue)

    从网上搜优先级队列用法,都是有些乱七八糟的,有几种用法都没说,直接贴代码.实在郁闷,于是自己在此归纳归纳. 废话不多说,直入主题. 优先级队列的核心是比较函数的实现. 比较函数有两种实现方法: 1.在 ...

  3. SQL Server 2017 安装问题(转)

    遇到问题 Polybase 要求安装 Oracle JRE7 更新 规则失败 安装完毕之后,登录提示:您试图连接的 SQL Server 实例未安装 安装完SQL Server 2017 后,无法启动 ...

  4. NGUI学习随笔

    一.NGUI的直接用法 1.      Attach a Collider:表示为NGUI的某些物体添加碰撞器,如果界面是用NGUI做的,只能这样添加.(注:用Component添加无效). 2.  ...

  5. Node-Blog整套前后端学习记录

    Node-Blog 后端使用node写的一个一整套的博客系统 #### 主要功能 登录 注册 发表文章 编辑/删除文章 添加/删除/编辑文章分类 账号的管理 评论功能 ... 所用技术 node ex ...

  6. ubuntu系统自动配置开机启动脚本

    以前一直搞的centos配置开机启动脚本,但是相同方法用在ubuntu系统上就不管用了,非常伤脑筋. 非常感谢  https://www.linuxidc.com/Linux/2017-09/1471 ...

  7. 00073_Math类

    1.Math类概述 (1)Math 类是包含用于执行基本数学运算的方法的数学工具类,如初等指数.对数.平方根和三角函数: (2)类似这样的工具类 ,其所有方法均为静态方法,并且一般不会创建对象.如Sy ...

  8. Profile 动态切换环境

    一.多 Profile 文件我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml默认使用 application.properties 的 ...

  9. Java多线程-锁的原理

    锁升级: 无锁->偏向锁->轻量级锁->重量级锁 sychronized原理: wait/notify

  10. HDU 1475 Pushing Boxes

    Pushing Boxes Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on PKU. Original ...