#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Version: python 3.6.3
# Tools: Pycharm 2017.3.3

__date__ = '2018/7/20 9:49'
__author__ = 'cdl'

import time
import threading

"""线程中的锁机制"""

"""
有两个线程A和B,A和B里的程序都加了同一个锁对象,当线程A率先执行到lock.acquire()(拿到全局唯一的锁后).
线程B只能等到线程A释放锁lock.release()后(归还锁)才能运行lock.acquire()(拿到全局唯一的锁)并执行后面的代码
"""
# 使用锁
lock = threading.Lock()  # 生成锁对象,全局唯一
lock.acquire()  # 获取锁。未获取到的线程会阻塞程序,直到获取到锁才会往下执行
lock.release()  #  释放锁,归回锁,其他线程可以拿去用了
# 注:lock.acquire() 和 lock.release()必须成对出现。否则就有可能造成死锁

# 为了避免出现死锁情况,推荐使用上下文管理器来加锁
lock = threading.Lock()
with lock:        # with语句会在这个代码块执行前自动获取锁,在执行结束后自动释放锁
    # 这里写自己的代码
    pass
# 使用锁的意义? -----------加锁是为了对锁内资源(变量)进行锁定,避免其他线程篡改已被锁定的资源,以达到我们预期的效果。
# 对比不用锁的线程
# def job1():
#     global n
#     for i in range(10):
#         n += 1
#         print('job1', n)
# def job2():
#     global n
#     for i in range(20):
#         n += 10
#         print('job2', n)
#
# n = 0
# threading_01 = threading.Thread(target=job1)
# threading_02 = threading.Thread(target=job2)
# threading_01.start()
# threading_02.start()
# 加锁之后进行对比
def job1():
    global n, lock
    lock.acquire()  # 获取锁
    for i in range(10):
        n += 1
        print('job1', n)
    lock.release()

def job2():
    global n, lock
    lock.acquire()  # 获取锁
    for i in range(10):
        n += 10
        print('job2', n)
    lock.release()
n = 0
lock = threading.Lock()  # 生成锁对象,全局唯一
threading_01 = threading.Thread(target=job1)
threading_02 = threading.Thread(target=job2)
threading_01.start()
threading_02.start()
# 有时候在同一个线程中,我们可能会多次请求同一资源(就是,获取同一锁钥匙),俗称锁嵌套
def main():
    n = 0
    lock = threading.Lock()
    with lock:
        for i in range(10):
            n += 1
            with lock:  # 第二次获取锁时,发现锁已经被同一线程的人拿走了。自己也就理所当然,拿不到锁,程序就卡住了。
                print(n)

t1 = threading.Thread(target=main)
t1.start()
# 可重入锁RLock,专门来处理这个问题
def num():
    n = 0
    # 生成可重入锁对象
    lock = threading.RLock()
    with lock:
        for i in range(10):
            n += 1
            with lock:
                print(n)

t1 = threading.Thread(target=num)
t1.start()
# 防止死锁的加锁机制
"""
出现情况:
同一线程,嵌套获取同把锁,造成死锁
多个线程,不按顺序同时获取多个锁。造成死锁
具体解释:
线程1,嵌套获取A,B两个锁,线程2,嵌套获取B,A两个锁。 
由于两个线程是交替执行的,是有机会遇到线程1获取到锁A,而未获取到锁B,在同一时刻,线程2获取到锁B,而未获取到锁A。
由于锁B已经被线程2获取了,所以线程1就卡在了获取锁B处,由于是嵌套锁,线程1未获取并释放B,是不能释放锁A的。
这是导致线程2也获取不到锁A,也卡住了。两个线程,各执一锁,各不让步,造成死锁。
"""
import threading
from contextlib import contextmanager

# Thread-local state to stored information on locks already acquired
_local = threading.local()

@contextmanager
def acquire(*locks):
    # Sort locks by object identifier
    locks = sorted(locks, key=lambda x: id(x))

# Make sure lock order of previously acquired locks is not violated
    acquired = getattr(_local,'acquired',[])
    if acquired and max(id(lock) for lock in acquired) >= id(locks[0]):
        raise RuntimeError('Lock Order Violation')

# Acquire all of the locks
    acquired.extend(locks)
    _local.acquired = acquired
    try:
        for lock in locks:
            lock.acquire()
        yield
    finally:
        # Release locks in reverse order of acquisition
        for lock in reversed(locks):
            lock.release()
        del acquired[-len(locks):]

x_lock = threading.Lock()
y_lock = threading.Lock()
def thread_1():
    while True:
        with acquire(x_lock):
            with acquire(y_lock):
                print('Thread-1')

def thread_2():
    while True:
        with acquire(y_lock):
            with acquire(x_lock):
                print('Thread-2')
t1 = threading.Thread(target=thread_1)
t1.daemon = True
t1.start()
t2 = threading.Thread(target=thread_2)
t2.daemon = True
t2.start()

python3多线程----锁机制相关推荐

  1. [java多线程] - 锁机制同步代码块信号量

    在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同 ...

  2. educoder 使用线程锁(lock)实现线程同步_Python并行编程(二):多线程锁机制利用Lock与RLock实现线程同步

    什么是锁机制? 要回答这个问题,我们需要知道为什么需要使用锁机制.前面我们谈到一个进程内的多个线程的某些资源是共享的,这也是线程的一大优势,但是也随之带来一个问题,即当两个及两个以上的线程同时访问共享 ...

  3. 详解 Java 常用的四种锁机制优缺点

    多线程的并发问题一直困扰着大家,Java提供了多种多线程锁机制的实现方式,接下来的话题将分为四个部分给大家讲解他们的优缺点和原理(Synchronized.ReentrantLock.Semaphor ...

  4. python3 多线程操作数据库锁机制问题

    场景:公司项目,采取多线程模式定时执行更新某些配置信息,当某两个或多个线程公用一个connect,execute某个sql语句的时候,会造成如下错误. Packey sequence number w ...

  5. 多线程高并发 底层锁机制与优化的最佳实践——各种锁的分类 || synchronized 关键字 倒底锁的是什么东西?|| CAS与ABA问题||锁优化||轻量级锁一定比重量级锁的性能高吗

    多线程高并发 底层锁机制与优化的最佳实践 各种锁的分类 加上synchronized 关键字,共享资源就不会出错 synchronized 关键字 倒底锁的是什么东西? synchronized 锁的 ...

  6. JUC多线程:synchronized锁机制原理 与 Lock锁机制

    前言: 线程安全是并发编程中的重要关注点,造成线程安全问题的主要原因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据.因此为了解决这个问题,我们可能需要这样一个方案,当存在多 ...

  7. java线程 锁_Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

  8. iOS面试题(二十五)多线程 --NSOperation和NSOperationQueueNSThread锁机制

    7.多线程 GCD(使用最多) NSOperation/NSOperationQueue(AFNetworking源码中所有网络请求任务都封装到NSOperation,提交到operationQueu ...

  9. Java 多线程 不使用锁机制 实现交替打印数字和字母

    Java 多线程 不使用锁机制 实现交替打印数字和字母 这是一道经典的面试题,使用两个线程去交替打印数字和字母,输出1A2B3C4D5E6F7G-这样的效果,看了网上很多的文章,基本都是使用Condi ...

最新文章

  1. asp.net 的性能计数器
  2. 用css绘制各种形状
  3. DevExpress中透明玻璃效果
  4. cassandra mongodb选择——cassandra:分布式扩展好,写性能强,以及可以预料的查询;mongodb:非事务,支持复杂查询,但是不适合报表...
  5. DedeCMS四类核心表
  6. dlut-KFQ人工智能导论答案1
  7. android 寺库trytry_寺库与美图达成战略合作美图美妆APP将由TryTry运营_联商网
  8. kali 19.2 搭建ftp服务器
  9. VB.NET与 sql数据库
  10. 当系统出错,win10真难用
  11. 使用cl编译器,将记事本写的c文件编译成dll和exe 步骤如下(记事本保存成.c)
  12. ArcMap制作城市道路网壁纸(OSM道路数据下载)
  13. java时间的格式化_java如何给时间格式化
  14. java retainall_Java Set retainAll()用法及代码示例
  15. Vlan是什么?定义,特点超详细解析
  16. alex机器人 ser_基于Web Service的机器人远程控制系统设计
  17. 数据分析师如何做数据分析汇报
  18. 二维码图片生成 hutool
  19. [考研经验]北京邮电大学软件学院2018年考研经验
  20. 年薪超过 50 万的程序员在哪些公司工作?

热门文章

  1. JS操作JSON总结
  2. iOS -- UIApplication
  3. Keypress - 捕获键盘输入的JavaScript库
  4. Java中System.getProperty()的参数
  5. 修改模拟器的IMEI号
  6. 增加了一行代码,让我们提高了3000%的性能
  7. 美团一面,看看你能否回答上来?
  8. 阿里飞猪搜索技术的应用与创新
  9. 一文带你了解 MySQL 中的各种锁机制!
  10. 我在硅谷工作的第四年:技术是怎么把信息变现的