1、基础概念

当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码、bug等异常行为。

竞争条件最简单的解决方法是使用锁。锁的操作非常简单,当一个线程需要访问部分共享内存时,它必须先获得锁才能访问。此线程对这部分共享资源使用完成之后,释放锁,然后其他线程才可再次获得锁并访问这部分资源。

然而,在实际使用中,这个方法经常导致死锁现象。当不同线程要求得到同一个锁时,死锁就会发生,此时程序不会继续执行,因为他们互相拿着对方需要的锁。

造成死锁的原因:线程A在使用资源2,线程B在使用资源1,如果在没有释放锁时,线程A又需要资源1,线程B又需要资源2,但是两个资源的锁都是被占用的,而且在对方的锁释放之前都处于等待且不释放锁的状态,此时就会造成死锁。

使用锁来解决同步问题是一个可行的方式,但是也存在潜在的问题。

2、使用Lock进行线程同步

示例:

# coding : utf-8

import threading

shared_resource_with_lock = 0
shared_resource_with_no_lock = 0
count = 100000 shared_resource_lock = threading.Lock() # has lock
def increment_with_lock():
global shared_resource_with_lock
for i in range(count):
shared_resource_lock.acquire()
shared_resource_with_lock += 1
shared_resource_lock.release()
def decrement_with_lock():
global shared_resource_with_lock
for i in range(count):
shared_resource_lock.acquire()
shared_resource_with_lock -= 1
shared_resource_lock.release() # has no lock
def increment_without_lock():
global shared_resource_with_no_lock
for i in range(count):
shared_resource_with_no_lock += 1 def decrement_without_lock():
global shared_resource_with_no_lock
for i in range(count):
shared_resource_with_no_lock -= 1 if __name__ == "__main__":
t1 = threading.Thread(target=increment_with_lock)
t2 = threading.Thread(target=decrement_with_lock)
t3 = threading.Thread(target=increment_without_lock)
t4 = threading.Thread(target=decrement_without_lock)
t1.start()
t2.start()
t3.start()
t4.start()
t1.join()
t2.join()
t3.join()
t4.join()
print("the value of shared with lock is %s" %shared_resource_with_lock)
print("the value of shared with no lock is %s" % shared_resource_with_no_lock)

执行结果:

在有锁的情况下,我们会得到挣钱的结果,而没有锁的情况下,往往会出现错误的结果。

3、锁状态

锁有两种状态:locked(被某一线程拿到)和unlocked(可用状态)

操作锁的方式:acquire()和release()

如果状态是unlocked,可以调用acquire将状态改为locked

如果状态是locked,acquire会被block直到另一个线程调用release释放锁

如果状态是unlocked,调用release会导致RuntimError异常

如果状态是locked,可以调用release将状态改为unlocked

Python并行编程(三):线程同步之Lock的更多相关文章

  1. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  2. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  3. .NET面试题解析(07)-多线程编程与线程同步

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...

  4. .NET面试题解析(07)-多线程编程与线程同步 (转)

    http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...

  5. python并发编程之线程/协程

    python并发编程之线程/协程 part 4: 异步阻塞例子与生产者消费者模型 同步阻塞 调用函数必须等待结果\cpu没工作input sleep recv accept connect get 同 ...

  6. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...

  7. Python并行编程(五):线程同步之信号量

    1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...

  8. Python并行编程(二):基于线程的并行

    1.介绍 软件应用中使用最广泛的并行编程范例是多线程.通常一个应用有一个进程,分成多个独立的线程,并行运行.互相配合,执行不同类型的任务. 线程是独立的处理流程,可以和系统的其他线程并行或并发地执行. ...

  9. Python并行编程的几个要点

    一.基于线程的并行编程 如何使用Python的线程模块 如何定义一个线程 如何探测一个线程 如何在一个子类中使用线程 Lock和RLock实现线程同步 信号实现线程同步 条件(condition)实现 ...

随机推荐

  1. CSS——div居中,window.open(0

    margin:0 auto 表示什么意思?? margin后面如果只有两个参数的话,第一个表示top和bottom,第二个表示left和right因为0 auto,表示上下边界为0,左右则根据宽度自适 ...

  2. eclipse 编译tomcat8.0.26的源码

    第一次写东西, 如果有不对的地方,请大神指正,我会尽快修正…… 参考:http://www.cnblogs.com/lanxuezaipiao/p/3640923.html 1.从tomcat官网(h ...

  3. PHP libevent扩展安装

    libevent是一个基于事件驱动的高性能网络库.支持多种 I/O 多路复用技术, epoll. poll. dev/poll. select 和 kqueue 等:支持 I/O,定时器和信号等事件: ...

  4. CI 多表关联查询

    方法一:$this->db->query("sql  语句");     直接写sql语句 方法二: #多表关联查询 $data=$this->db->fr ...

  5. SSIS 自测题-文件操作类

    说明:以下是自己的理解答案,不是标准的答案,如有不妥烦请指出.         有些题目暂时没有答案,有知道的请留言,互相学习,一起进步. 1.什么是控制流,什么是数据流,控制流和数据流之间的关系是什 ...

  6. 通过http输出流的方式从将html写入到Excel

    private void HtmlResponseToExecl() { //将数据(html)导入到Excel中 Response.Charset = "gb2312"; Res ...

  7. svn & git 问题汇总

    svn: warning: W150002: '/Users/piercalex/svn/azzz/1' is already under version control svn: E200009: ...

  8. 【BZOJ】1682: [Usaco2005 Mar]Out of Hay 干草危机(kruskal)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1682 最小生成树裸题.. #include <cstdio> #include < ...

  9. php如何优化压缩的图片

    php程序开发中经常涉及到生成缩略图,利用php生成缩略图这个过程本身没难度,但是你知道php能够优化调节生成的缩略图的质量吗?也就是说php能够控制生成缩略图的清晰度以及生成后的缩略图的体积.下面我 ...

  10. hdu 1147:Pick-up sticks(基本题,判断两线段相交)

    Pick-up sticks Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...