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

    http://www.360doc.com/content/15/0103/14/110467_437739376.shtml 解决方案: (1)视图——其他窗口——属性管理器. 注意:是”属性管理器 ...

  2. 【深入理解Java虚拟机】自动内存管理机制——垃圾回收机制

      Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来.C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生 ...

  3. 【LibreOJ 6278】 数列分块入门 2 (分块)

    题目原址 给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的元素个数. code: #include<cstdio> #include<iostream& ...

  4. vue项目使用简略总结

    1.利用iView Cli搭建项目结构2.搭建完毕之后将proxy.js和'Server.js'放置到node_modules\webpack-dev-server\lib目录下,以实现跨域访问公司平 ...

  5. Python面向对象----多态和鸭子类型

    1. C#中多态实现的条件是 继承, 重写以及父类指向子类. 但是在弱类型Python里面, 实现多态的条件就显得很简洁, 只需要在子类中实现父类相同名称的方法即可. 2. 鸭子类型的解释: 若一个类 ...

  6. tp3.1 白板不报错

    今天有碰上了这种情况, 一般记忆力好把刚才改动的地方恢复一下就好了,但是今天特殊原因编辑器不小心关了,也不知道把那里改坏了,一通乱找,也找不到.汗! 没办法,提交代码几面,用git看下改变的地方,是c ...

  7. 【Codeforces Round #507 (Div. 2, based on Olympiad of Metropolises) A】Palindrome Dance

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] i从1..n/2循环一波. 保证a[i]和a[n-i+1]就好. 如果都是2的话填上min(a,b)*2就好 其他情况跟随非2的. ...

  8. JavaScript之this释疑

    近期进修JavaScript,看了"You Don't Know JS"这本书,认为是本JavaScript内功上乘心法,有一定JavaScript基础朋友一定要看看(不推荐入门小 ...

  9. RabbitMQ从入门到精通

    RabbitMQ从入门到精通 学习了:http://blog.csdn.net/column/details/rabbitmq.html RabbitMQ是AMQP(advanced message ...

  10. 基于Solr的HBase实时查询方案

    实时查询方案 HBase+Solr+HBase-Indexer 1.HBase提供海量数据存储 2.solr提供索引构建与查询 3.HBase indexer提供自己主动化索引构建(从HBase到So ...