多线程、互斥锁、异步、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.主 ...
随机推荐
- Python之必备函数
1. lambda 表达式 匿名函数(ANONYMOUS FUNCTION)是指一类无需定义标识符(函数名)的函数.通俗来讲,就是它可以让我们的函数,可以不需要函数名. 正常情况下,我们定义一个函数, ...
- Excel 常用属性的一小部分
1.由于工作需要,最近积累了一些Excel中的相关知识,特此记录 Workbooks xlbooks = xlApp.Workbooks; Workbook xlbook = xlbooks.Add( ...
- html css+div+jquery实现图片轮播
一直想自己动手做一个图片轮播的控件,查查网上的资料大多引用已经做好的组件,其原理算法不是很清楚,于是自己用jquery写了一个.先看下效果图: 主要界面实现思路如下: 1.新建一个div宽度为100% ...
- ejabberd之开题篇
ejabberd是基于Jabber/XMPP协议的即时通讯服务器.采用Erlang/OTP开发.它的特点是,跨平台,容错,集群和模块化. 因为自己本身是基于erlang工作,而且听到有不少的公 ...
- idea 里自动下载私服jar一直不能下载下来
idea 里自动下载私服jar一直不能下载下来,只生成了.lastUpdated文件,检查了setting.xml文件.网络,私服,均无问题,在idea中打开Terminal窗口,在所要更新的pom. ...
- QWaitConditioin的思考1
16:50:392017-03-31 本文章为原创,如若引用请指明出处,否则追责. 以 生产.消费者的例子说明 #include <QtCore/QCoreApplication>#inc ...
- 在Design界面直接拖放控件的时候,提示AS- This view is not constrained vertically. At runtime it will jump to the left/(0,0) unless you
AS- This view is not constrained vertically. At runtime it will jump to the left/(0,0) unless you ad ...
- Altium Designer 10 执行DRC发现有 Length Constraint 解决办法
在PCB布局连线结束后,执行DRC,结果Length Constraint 报错,如图: 在Design Rules中找对应的规则约束,怎么也找不见. 其实是,在差分对进行等长蛇形绕线的步骤中,约束了 ...
- Linux安装配置rabbitmq
Step1:安装erlang 1)下载erlang wget http://www.rabbitmq.com/releases/erlang/erlang-19.0.4-1.el7.centos.x8 ...
- postman导入csv文件,批量运行
1.设置csv文件,第一行必须标明变量名 2.postman参数化设置 3.批量 run即可