# 任何语言都会发生多线程,会出现不同步的问题,同步锁、死锁、递归锁
# 异步: 多任务, 多个任务之间执行没有先后顺序,可以同时运行,执行的先后顺序不会有什么影响,存在的多条运行主线
# 同步: 多任务, 多个任务之间执行的时候要求有先后顺序,必须一个先执行完成之后,另一个才能继续执行, 只有一个主线
# 阻塞:从调用者的角度出发,如果在调用的时候,被卡住,不能再继续向下运行,需要等待,就说是阻塞
# 非阻塞: 从调用者的角度出发, 如果在调用的时候,没有被卡住,能够继续向下运行,无需等待,就说是非阻塞
# 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. jQuery中cookie使用方法

    <script type="text/javascript"> $(function () { var content=$.cookie('text');  //得到c ...

  2. 原生node写一个静态资源服务器

    myanywhere 用原生node做一个简易阉割版的anywhere静态资源服务器,以提升对node与http的理解. 相关知识 es6及es7语法 http的相关网络知识 响应头 缓存相关 压缩相 ...

  3. django rest-farme-work 的使用(3)

    请求和响应 Requests and Responses 从这一片来说,我们将真正开始覆盖REST框架的核心.我们来介绍一些基本的构建块 Request objects REST框架引入了一个Requ ...

  4. Linux设备驱动--块设备(二)之相关结构体(转)

    上回最后面介绍了相关数据结构,下面再详细介绍 块设备对象结构 block_device 内核用结构block_device实例代表一个块设备对象,如:整个硬盘或特定分区.如果该结构代表一个分区,则其成 ...

  5. 关于NumPy的坑

         初次接触NumPy的时候,感叹这个功能的强大,实现了Python对矩阵的运算,但在写一个项目的时候,发现了一个巨坑无比的情况     分隔符=================     对于被 ...

  6. 【CodeForces 271D】Good Substrings

    [链接] 我是链接,点我呀:) [题意] [题解] 字典树 我们可以两重循环(i,j) 来枚举所有的子串 即i=1,j=1,2,3... i=2,j = 2,3,4,.. 于是我们在i变化的时候(就是 ...

  7. spring 组件注册

    一.声明配置类和注册 bean /** * 配置类 == applicationContext.xml 配置文件 * @author Administrator * */ //@Configurati ...

  8. TeamTalk Android代码分析(业务流程篇)

    TeamTalk Android代码分析(业务流程篇) 1.1 总体结构 1.总体结构有点类似MVC的感觉,模块结构从上向下大体是: UI层:Activity和Fragment构成,期间包括常用的一些 ...

  9. BestCoder Round #75 King&#39;s Order dp:数位dp

    King's Order Accepts: 381 Submissions: 1361 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 655 ...

  10. 学习笔记一:关于directx sdk的安装于一些概念

    关于directx sdk开发环境的安装: 在百度搜索了directx sdk,进入了微软的官网,下载了DXSDK_Jun10.exe 百度网盘:http://pan.baidu.com/s/1o6r ...