python高级编程——锁
锁
使用锁:
锁的语法
创建锁、锁定锁、释放锁
from threading import Lock # 创建锁
mutex = Lock()
# 获取锁(上锁)
mutex.acquire()
# 释放锁(解锁)
mutex.release()
在锁定锁的过程中acquire()方法可以接受一个blocking参数,
如果设定blocking为True,则当前线程会堵塞,直到获取到这个锁为止(如果没有 指定,那么默认为True)
如果设定blocking为False,则当前线程不会堵塞
上锁和解锁的过程(假设是多线程调度):
这个锁一般是为共享资源服务的,即多个线程同时使用共享资源。这个锁同一时间只能有一个线程调度,其他线程阻塞,只有当前调度的线程释放这个锁,阻塞的线程才能调度。
锁的优点:
确保了某段关键代码只能有一个线程从头到尾完整的执行。
锁的缺点:
组织了多线程的并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大的降低了;代码中可能存在多个锁,如果多个线程拥有多个锁,容易造成死锁。
死锁的现象(实例):
# 死锁 两者都没有释放对方需要的锁,而释放的条件恰好是获取对方释放所需要的锁
# 线程1
class MyThread1(threading.Thread):
def __init__(self):
super().__init__() def run(self):
# 线程1获取A锁
if mutexA.acquire():
print(self.name+"-----do1---up-----")
sleep(1)
# 此时线程2获取了B锁,需要等待线程2释放B锁
if mutexB.acquire():
print(self.name + "-----do1---down-----")
mutexB.release()
mutexA.release() # 线程2
class MyThread2(threading.Thread):
def __init__(self):
super().__init__() def run(self):
# 线程2获取B锁
if mutexB.acquire():
print(self.name + "-----do2---up-----")
sleep(1)
# 此时线程1获取了A锁,需要等待线程1释放A锁
if mutexA.acquire():
print(self.name + "-----do2---down-----")
mutexA.release()
mutexB.release() mutexA = threading.Lock()
mutexB = threading.Lock() if __name__ == '__main__':
# 线程1和线程2同时执行
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
避免死锁的方法:银行家算法
多进程与多线程比较及选择
是否采用多任务处理,取决于我们的任务类型
如果是计算密集型,需要大量的CPU资源进行运算,代码的运行效率至关重 要,这样的任务一般不使用多线程进行,因为频繁的任务调度会拖慢CPU的
运算。
如果是IO密集型,涉及到硬盘读写,网络读写等的任务,更多的时间在等待 IO操作完成,这一类任务可以放到多线程或多进程中来进行。
单线程、多线程、多进程(一起实现同一代码的时间)
# 单线程、多线程、多进程的使用及不同
# 简单的求和
def fib(x):
res = 0
for i in range(100000000):
res += i*x
return res # 阶乘
def fac(x):
if x < 2:
return 1
return x*fac(x-1) # 简单的求和
def sum(x):
res = 0
for i in range(50000000):
res += i*x
return res # 函数列表
funcs = [fib, fac, sum]
n = 100 class MyThread(threading.Thread):
def __init__(self, func, args, name=""):
super().__init__()
self.name = name
self.func = func
self.args = args
self.res = 0 def getResult(self):
return self.res def run(self):
print("starting ", self.name, " at: ", ctime())
self.res = self.func(self.args)
print(self.name, "finished at: ", ctime()) def main():
nfuncs = range(len(funcs)) print("单线程".center(30, "*"))
start = time()
for i in nfuncs:
print("start {} at: {}".format(funcs[i].__name__, ctime()))
start_task = time()
print(funcs[i](n))
end_task = time()
print("任务 耗时:", end_task-start_task)
print("{} finished at: {}".format(funcs[i].__name__, ctime())) end = time()
print("单线程运行时间:", end-start)
print("单线程结束:".center(30, "*")) print()
print("多线程".center(30, "*"))
start = time()
threads = []
for i in nfuncs:
# 一个线程绑定一个函数
t = MyThread(funcs[i], n, funcs[i].__name__)
threads.append(t) for i in nfuncs:
# 同时启动线程
threads[i].start() for i in nfuncs:
threads[i].join()
print(threads[i].getResult())
end = time()
print("多线程运行时间:", end-start)
print("多线程结束:".center(30, "*")) print()
print("多进程".center(30, "*"))
start = time()
process_list = []
for i in nfuncs:
# 一个进程绑定一个函数
t = Process(target=funcs[i], args=(n, ))
process_list.append(t) for i in nfuncs:
# 同时启动进程
process_list[i].start() for i in nfuncs:
process_list[i].join()
end = time()
print("多进程运行时间:", end - start)
print("多进程结束:".center(30, "*")) if __name__ == "__main__":
main()
python高级编程——锁的更多相关文章
- 第十章:Python高级编程-多线程、多进程和线程池编程
第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...
- python高级编程:有用的设计模式3
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...
- python高级编程:有用的设计模式2
# -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...
- python高级编程:有用的设计模式1
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...
- python高级编程技巧
由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr ...
- python高级编程之选择好名称:完
由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- python高级编程之列表推导式
1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...
- Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍
原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...
随机推荐
- python 正则表达式提取返回内容
import re re.findall(' <input name="address_id" type="hidden" value="(.* ...
- luoguP1198 [JSOI2008]最大数
https://www.luogu.org/problem/P1198 update!!! 经过老师的讲解,惊人的发现这题有用更简单数据结构维护的解法,而越简单的数据结构(如果能够用的话),越好(实现 ...
- E09【餐厅】Can I have the bill,please?
核心句型: Can I have the bill ,please? 请给我账单,好吗? 场景对话: A:Excuse me. Can I have the bill ,please? 你好,请给我账 ...
- 1.Vue前端核心分析
1.Vue SoC:关注点分离原则 网络通信:axios 页面跳转:vue-router 页面管理:vuex Vue-UI:ICE.ElementUI 集大成者:MVVM+虚拟DOM 2.MVVM 异 ...
- 数据结构——顺序队列(sequence queue)
/* sequenceQueue.c */ /* 顺序队列 */ #include <stdio.h> #include <stdlib.h> #include <std ...
- luoguP4213 【模板】杜教筛(Sum)杜教筛
链接 luogu 思路 为了做hdu来学杜教筛. 杜教筛模板题. 卡常数,我加了register居然跑到不到800ms. 太深了. 代码 // luogu-judger-enable-o2 #incl ...
- MySQL实战45讲学习笔记:第六讲
一.今日内容概要 今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重 ...
- [LeetCode] 711. Number of Distinct Islands II 不同岛屿的个数之二
Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...
- [LeetCode] 321. Create Maximum Number 创建最大数
Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum numb ...
- 一次失败的尝试:arm(aarch64架构)上使用docker运行Gogs
环境 Ubuntu aarch64(好像是arm8的一种) Docker安装指南:https://docs.docker.com/install/linux/docker-ce/ubuntu/ Gog ...