一、锁在多线程中的使用:线程互斥
lock = threading.Lock()#创建一个锁对象
1、with lock:
pass
和进程使用的方式相同
 
2、控制线程结束的时间
通过一个全局变量
# encoding=utf-8
import threading,time,Queue,random
 
exitFlag = False
def write(lock,queue):
while exitFlag != True:
with lock:
data = random.randint(1,100)
print 'put:',data
queue.put(data)
time.sleep(1)
 
def read(queue):
while exitFlag != True:
print 'get:',queue.get()
time.sleep(1)
 
if __name__ == '__main__':
lock = threading.Lock()
queue = Queue.Queue()
t1 = threading.Thread(target=write,args=(lock,queue))
t2 = threading.Thread(target=write,args=(lock,queue))
t3 = threading.Thread(target=read,args=(queue,))
t1.start()
t2.start()
t3.start()
time.sleep(10)
exitFlag = True
t1.join()
t2.join()
t3.join()
 
二、线程同步
1、生产者--消费者模式
Queue() 作为生产者和消费者的中介
from
 
class Producer(threading.Thread):
def __init__(self,t_name,queue):
threading.Thread.__init__(self,name=t_name)#继承父类的构造方法的目的:初始化一些线程实例,
self.data=queue
def run(self):
for i in xrange(5):
print '%s:%s is producing %d to the queue\n'%(time.ctime(),self.getname(),i)
self.data.put(i)
time.sleep(2)
print '%s:%s put finished \n'%(time.ctime(),self.getname(),i)
def Consumer(threading.Thread):
def __init__(self,t_name,queue):
threading.Thread.__init__(self,name=t_name)
self.data=queue
def run(self):
for i in xrange(5):
val=self.data.get()
print '%s:%s is consumer %d in the queue\n'%(time.ctime(),self.getname(),val)
print '%s:%s consumer finished \n'%(time.ctime(),self.getname(),i)
 
if __name=='__main__':
queue=Queue()#没有制定队列大小,默认为无限大,可以不受限制的放入队列
producer=Producer('Pro',queue)
consumer=Consumer('Con',queue)
producer.start()
time.sleep(1)
consumer.start()
producer.join()
consumer.join()
print 'mainThread end'
 
2、Event 信号传递
event=threading.Event()
import threading,time,Queue,random
 
def write(lock,queue,event):
while not event.isSet():
with lock:
thread = threading.currentThread()
data = random.randint(1,100)
print 'this is thread:',thread.getName(),'put:',data
queue.put(data)
time.sleep(1)
 
def read(queue):
while not event.isSet():
print 'get:',queue.get()
time.sleep(1)
 
if __name__ == '__main__':
lock = threading.Lock()
queue = Queue.Queue()
event=threading.Event()
t1 = threading.Thread(target=write,args=(lock,queue,event))
t2 = threading.Thread(target=write,args=(lock,queue,event))
t3 = threading.Thread(target=read,args=(queue,))
t1.start()
t2.start()
t3.start()
time.sleep(10)
event.set()
t1.join()
t2.join()
t3.join()
3、lock :只能加一把锁
4、semaphore:可以加多把锁
设置限制最多3个线程同时访问共享资源:s = threading.Semaphore(3)
5、event:线程等待某一时间的发生,之后执行逻辑
6、Condition 条件
con=threading.Condition()
使用场景:处理复杂的逻辑。基于锁来实现的
两个线程之间做一些精准的通信
线程A做了某一件事,中途需要停止
线程B做另外一件事情,线程B通知线程A
线程A继续
(1)额外提供了wait()方法和notify()方法,用于处理复杂的逻辑
(2)wait()释放锁,并且等待通知
(3)Notify()唤醒对方,可以继续下去。但是需要两个线程之间需要抢锁,谁抢到执行谁
通过(2)和(3),实现线程间的通信。
import threading
import time
product = 0
exitFlag = False
def consumer(con):
global product
while exitFlag != True:
with con:
print 'enter consummer thread'
if product == 0:
con.wait()
else:
print 'now consummer 1 product'
product -= 1
print 'after consummer, we have ',product,'product now'
time.sleep(2)
 
def producer(con):
global product
while exitFlag != True:
with con:
print 'enter producer thread'
product += 1
con.notify()
print 'after producer, we have ', product, 'product now'
time.sleep(2)
 
if __name__ == '__main__':
con = threading.Condition()
c1 = threading.Thread(target=consumer,args=(con,))
p1 = threading.Thread(target=producer, args=(con,))
 
c1.start()
p1.start()
time.sleep(6)
exitFlag = True
c1.join()
p1.join()
 
7、死锁
t1:拥有lock1锁,申请lock2锁
t2:拥有lock2锁,申请lock1锁
(1)如何尽量的保证不出现死锁:
定义锁的使用顺序

Python之多线程:线程互斥与线程同步的更多相关文章

  1. python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  2. linux c编程:线程互斥二 线程死锁

    死锁就是不同的程序在运行时因为某种原因发生了阻塞,进而导致程序不能正常运行.阻塞程序的原因通常都是由于程序没有正确使用临界资源. 我们举个日常生活中的例子来比喻死锁.我们把马路上行驶的汽车比作运行着的 ...

  3. (day29) 进程互斥锁 + 线程

    目录 进程互斥锁 队列和堆栈 进程间通信(IPC) 生产者和消费者模型 线程 什么是线程 为什么使用线程 怎么开启线程 线程对象的属性 线程互斥锁 进程互斥锁 进程间数据不共享,但是共享同一套文件系统 ...

  4. python中多线程相关

    基础知识 进程:进程就是一个程序在一个数据集上的一次动态执行过程 数据集:程序执行过程中需要的资源 进程控制块:完成状态保存的单元 线程:线程是寄托在进程之上,为了提高系统的并发性 线程是进程的实体 ...

  5. JAVA多线程提高二:传统线程的互斥与同步&传统线程通信机制

    本文主要是回顾线程之间互斥和同步,以及线程之间通信,在最开始没有juc并发包情况下,如何实现的,也就是我们传统的方式如何来实现的,回顾知识是为了后面的提高作准备. 一.线程的互斥 为什么会有线程的互斥 ...

  6. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  7. Python多线程(2)——线程同步机制

    本文介绍Python中的线程同步对象,主要涉及 thread 和 threading 模块. threading 模块提供的线程同步原语包括:Lock.RLock.Condition.Event.Se ...

  8. python学习笔记-(十三)线程&多线程

    为了方便大家理解下面的知识,可以先看一篇文章:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 线程 1.什么是线程? ...

  9. Python 学习入门(22)—— 线程同步

    Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 ...

随机推荐

  1. 使用myeclipse创建servlet后输入地址无法访问

    问题: 使用myeclipse创建servlet后输入地址无法访问 1.首先,路径的访问地址是在web.xml里设置的,一般会自动生成(但是可能会和你自己输入的有出入) 你必须按照<url-pa ...

  2. 深入理解PHP数组函数和预定义接口

    一. PHP对数组的过滤 函数: array_filter(p1[,p2]) 参数p1是要过滤的数组,参数p2是自定义过滤会掉函数(可以是匿名函数) 例子: <?php $arr = ['',n ...

  3. MAC下MySQL初始密码忘记修改初始密码

    解决MAC下MySQL忘记初始密码的方法分享给大家,供大家参考,具体内容如下 第一步: 点击系统偏好设置->最下边点MySQL,在弹出页面中,点击stop MySQL Servier,输入密码关 ...

  4. パラメータID一覧

    名称 内容 ABK 処理グループ. AUF 受注伝票タイプ. AVE FI:支払明細通知書のテンプレート登録. BAR 伝票タイプ. BNK 銀行コード. BUK 会社コード. CAC 管理領域. D ...

  5. scrapy如何实现分布式爬虫

    使用scrapy爬虫的时候,记录一下如何分布式爬虫问题: 关键在于多台主机协作的关键:共享爬虫队列 主机:维护爬取队列从机:负责数据抓取,数据处理,数据存储 队列如何维护:Redis队列Redis 非 ...

  6. 8,实例化Flask的参数 及 对app的配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  7. mysql安装与基本管理,mysql密码破解

    一.MySQL介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是 ...

  8. compileReleaseJavaWithJavac

    如果你打release 包的时候,出现这个问题,那么请你先跑一下程序,肯定是有什么方法名,或者什么东西没找到. release 的时候不会报错,只有你跑的时候才会报错.

  9. C++的字符输入

    字符串的输入有6中方式,这六种方式各有各的特点,我这篇学习笔记是自己的经验总结,没有去探讨内存,函数库等的复杂问题,仅仅是为了实用: 第一:cin cin一次接受一个字符,所以有的人会选择定义一个字符 ...

  10. webdriver--定位一组元素+iframe表单切换

    定位一组元素:find_elements,返回的是list,所以可以用列表的索引对列表里的某个元素操作,也可以用for循环访问list,依次操作各元素 driver.find_elements_by_ ...