多线程、互斥锁、异步、GIL
多线程-threading
python的thread模块是比较底层的模块,python的threading模块是对thread做了一些包装的,可以更加方便被使用
from threading import Thread import time def test():
print("---1---")
time.sleep(1) for i in range(5):
t = Thread(target=test)
t.start()
输出
---1---
---1---
---1---
---1---
---1---
主线程等待子线程都执行完后才退出
使用thread子类创建线程
import threading
import time class MyThread(threading.Thread):
def run(self):
msg = "I'm" + self.name + " @ " + str(i) # self.name是当前线程的名字
print(msg)
time.sleep(1) for i in range(5):
t = MyThread()
t.start()
输出
I'm Thread-1 @ 0
I'm Thread-2 @ 1
I'm Thread-3 @ 2
I'm Thread-4 @ 3
I'm Thread-5 @ 4
线程的执行顺序
import threading
import time class MyThread(threading.Thread):
def run(self):
for i in range(3):
msg = "I'm " + self.name + " @ " + str(i) # self.name是当前线程的名字,也可以用threading.current_thread().name获取当前线程的名字
print(msg)
time.sleep(1) for i in range(5):
t = MyThread()
t.start()
输出
I'm Thread-1 @ 0
I'm Thread-2 @ 0
I'm Thread-3 @ 0
I'm Thread-4 @ 0
I'm Thread-5 @ 0
I'm Thread-1 @ 1
I'm Thread-3 @ 1
I'm Thread-2 @ 1
I'm Thread-5 @ 1I'm Thread-4 @ 1 I'm Thread-1 @ 2
I'm Thread-2 @ 2
I'm Thread-3 @ 2
I'm Thread-5 @ 2I'm Thread-4 @ 2
线程共享全局变量
from threading import Thread
import time g_num = 100 def test1():
global g_num
for i in range(3):
g_num += 1
print("---in test1, g_num is %d---"%g_num) def test2():
global g_num
print("---in test2, g_num is %d---" % g_num) print("---线程创建之前g_num is %d---"%g_num) t1 = Thread(target=test1)
t1.start()
time.sleep(1)
t2 = Thread(target=test2)
t2.start()
输出
---线程创建之前g_num is 100---
---in test1, g_num is 103---
---in test2, g_num is 103---
互斥锁
#创建锁
mutex = threading.Lock()
#锁定
mutex.acquire([blocking])
#释放
mutex.release()
当多个线程要修改同一个全局变量时,要用互斥锁
g_num = 0 def test1():
global g_num
for i in range(10000):
mutex.acquire()
g_num += 1
mutex.release()
print("--- test1 g_num=%d ---" % g_num) def test2():
global g_num
for i in range(10000):
mutex.acquire()
g_num += 1
mutex.release()
print("--- test2 g_num=%d ---" % g_num) mutex = Lock() t1 = Thread(target=test1)
t1.start() t2 = Thread(target=test2)
t2.start() print("--- g_num=%d ---"%g_num)
输出
---test1 g_num=10000---
---test2 g_num=20000---
注意:第一次上锁程序不会锁住,第二次在没有解锁的情况下上锁程序才会锁住。
总结:
1、线程共享全局变量。
2、线程不共享函数里面的代码。
3、非全局变量不需要加锁 。
4、加锁的代码越少越好。
5、主线程等待子线程都执行完后才退出。
ThreadLocal对象
⼀个ThreadLocal变量虽然是全局变量,但每个线程都只能读写⾃⼰线程的独 ⽴副本,互不⼲扰。ThreadLocal解决了参数在⼀个线程中各个函数之间互相传递的问题。
import threading local_school = threading.local() def process_student():
# 获取当前线程关联的student:
std = local_school.student
print("hello, %s (in %s)"%(std, threading.current_thread().name)) def process_thread(name):
# 绑定ThreadLocal的student
local_school.student = name
process_student() t1 = threading.Thread(target=process_thread,args=("老李",), name="Thread-A")
t2 = threading.Thread(target=process_thread,args=("老王",), name="Thread-B")
t1.start()
t2.start()
#这里可以不加join
t1.join()
t2.join()
输出
hello, 老李 (in Thread-A)
hello, 老王 (in Thread-B)
ThreadLocal最常⽤的地⽅就是为每个线程绑定⼀个数据库连接,HTTP请求,⽤户身份信息等,这样⼀个线程的所有调⽤到的处理函数都可以⾮常⽅便地访问这些资源。
异步
from multiprocessing import Pool
import time
import os def test():
print("---进程池中的进程--pid=%d,ppid=%d---"%(os.getpid(),os.getppid()))
for i in range(3):
print("---%d---"%i)
time.sleep(1)
return "hahah" def test2(args):
print("---callback func--pid=%d"%os.getpid())
print("---callback func--args=%s"%args) if __name__ == '__main__':
pool = Pool(3)
pool.apply_async(func=test,callback=test2)
while True:
time.sleep(1)
print("---主进程--pid=%d---"%os.getpid())
输出
---进程池中的进程--pid=9228,ppid=3520---
---0---
---主进程--pid=3520---
---1---
---主进程--pid=3520---
---2---
---主进程--pid=3520---
---callback func--pid=3520 #pid为主进程id,也就是说主进程放下手中的工作,开始执行test2函数,这就是异步。
---callback func--args=hahah
---主进程--pid=3520---
---主进程--pid=3520---
---主进程--pid=3520---
...
GIL也就是全局解释器锁,GIL保证一个进程里,同一时间只有一个线程在执行任务,只在cpython解释器里有GIL,jpython解释器就没有。
python里的多线程实际上是假多线程。
python里的多进程是真的多进程。
多线程、互斥锁、异步、GIL的更多相关文章
- 6-[多线程]-互斥锁、GIL、死锁、递归锁、信号量
1.互斥锁(排他锁) (1)不加锁的情况下 并发控制问题:多个事务并发执行,可能产生操作冲突,出现下面的3种情况 丢失修改错误 不能重复读错误 读脏数据错误 # mutex from threadin ...
- 并发编程 - 线程 - 1.互斥锁/2.GIL解释器锁/3.死锁与递归锁/4.信号量/5.Event事件/6.定时器
1.互斥锁: 原理:将并行变成串行 精髓:局部串行,只针对共享数据修改 保护不同的数据就应该用不用的锁 from threading import Thread, Lock import time n ...
- Python Threading 线程/互斥锁/死锁/GIL锁
导入线程包 import threading 准备函数线程,传参数 t1 = threading.Thread(target=func,args=(args,)) 类继承线程,创建线程对象 class ...
- C++ windows 多线程 互斥锁
#include <opencv2/core/version.hpp> #include <opencv2/calib3d/calib3d.hpp> #include < ...
- java基础-多线程互斥锁
多线程(JDK1.5的新特性互斥锁)* 1.同步 * 使用ReentrantLock类的lock()和unlock()方法进行同步* 2.通信 * 使用ReentrantLock类的newCondit ...
- python 并发编程 多线程 互斥锁
互斥锁 并行变成串行,牺牲效率 保证数据安全,实现局部串行 保护不同的数据,应该加不同的锁 现在一个进程 可以有多个线程 所有线程都共享进程的地址空间 实现数据共享 共享带来问题就会出现竞争 竞争就会 ...
- Python多线程互斥锁
import threading import time num=0 def Mylock(lock): global num lock.acquire() num=num+1 time.sleep( ...
- 笔记1 linux 多线程 互斥锁
//mutex lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test ...
- 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁
一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...
- python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)
9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕详细解释:1.主 ...
随机推荐
- ajax成功返回结果字符串,对比不成功的解决办法
这是很久之前遇到的问题了,今天不小心又遇到了,总结了一下以前处理的办法. 废话不说,上代码: $.ajax({ url:"exit.do", data:{account:accou ...
- MHA(上)
一.mysql-mha环境准备 1.准备工作 1.1 实验环境: 1.2 软件包 用到的所有包 链接:https://pan.baidu.com/s/19tiKXNEW4C6oWi9OFmcDYA 提 ...
- configparser模块(ini配置文件生成模块)
config = configparser.ConfigParser() #初始化config对象 [DEFAULT] #设置默认的变量值,初始化 config["DEFAULT" ...
- 赚钱快的app
赚钱快的app目前强力推荐6款都是很不错的 宝石星球下载地址:http://www.baoshixingqiu.com/redPacket?key=548341 雪梨网APP下载地址 http://w ...
- jQuery-4.动画篇---动画切换的比较(toggle与slideToggle以及fadeToggle的比较)
jQuery中toggle与slideToggle以及fadeToggle的比较 操作元素的显示和隐藏可以有几种方法.例如: 改变样式display为none 设置位置高度为0 设置透明度为0 都能达 ...
- I/O 模型与 Java
本文主要记录 Java 中 I/O 模型及相关知识点 .另,由于自身知识水平有限,如有不正之处,望各位能够谅解,欢迎批评指正! 一.I/O 基础 由于 Java 中 I/O 相关的 API ,无论是 ...
- python学习5---实现凸包
1.暴力法 def g(A,B,P): """ 判断点PA矢量在AB矢量的顺时针还是逆时针方向, 若在逆时针方向则返回1,同向返回0,在顺时针方向返回-1 :param ...
- Egret_简单的封装方法
////////////随机颜色***////////////////////////// private getRdmClr(): number { return (Math.floor(Math. ...
- vue—data中变量和字符串拼接
#变量和字符串的拼接# 写项目中,遇到了这样的一个问题:怎样在一个div里面显示两个data中的数据?我的问题描述清楚了吗?... 看图吧: 这是用户最初的需求~ 这是用户后来的需求,嗯……就是 ...
- Windows Server 2012配置iis遇到的问题
发布网站访问时报500 - 内部服务器错误,经排查是Windows Server 2012上的iis配置有问题,有些需要的功能没有配置. 在重新配置iis时总是安装失败,提示存储空间不足. 在网上查找 ...