多线程-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的更多相关文章

  1. 6-[多线程]-互斥锁、GIL、死锁、递归锁、信号量

    1.互斥锁(排他锁) (1)不加锁的情况下 并发控制问题:多个事务并发执行,可能产生操作冲突,出现下面的3种情况 丢失修改错误 不能重复读错误 读脏数据错误 # mutex from threadin ...

  2. 并发编程 - 线程 - 1.互斥锁/2.GIL解释器锁/3.死锁与递归锁/4.信号量/5.Event事件/6.定时器

    1.互斥锁: 原理:将并行变成串行 精髓:局部串行,只针对共享数据修改 保护不同的数据就应该用不用的锁 from threading import Thread, Lock import time n ...

  3. Python Threading 线程/互斥锁/死锁/GIL锁

    导入线程包 import threading 准备函数线程,传参数 t1 = threading.Thread(target=func,args=(args,)) 类继承线程,创建线程对象 class ...

  4. C++ windows 多线程 互斥锁

    #include <opencv2/core/version.hpp> #include <opencv2/calib3d/calib3d.hpp> #include < ...

  5. java基础-多线程互斥锁

    多线程(JDK1.5的新特性互斥锁)* 1.同步 * 使用ReentrantLock类的lock()和unlock()方法进行同步* 2.通信 * 使用ReentrantLock类的newCondit ...

  6. python 并发编程 多线程 互斥锁

    互斥锁 并行变成串行,牺牲效率 保证数据安全,实现局部串行 保护不同的数据,应该加不同的锁 现在一个进程 可以有多个线程 所有线程都共享进程的地址空间 实现数据共享 共享带来问题就会出现竞争 竞争就会 ...

  7. Python多线程互斥锁

    import threading import time num=0 def Mylock(lock): global num lock.acquire() num=num+1 time.sleep( ...

  8. 笔记1 linux 多线程 互斥锁

    //mutex lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test ...

  9. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

  10. python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)

    9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕​详细解释:1.主 ...

随机推荐

  1. c++单链表冒泡排序(交换结点),链表增删改查,运算符重载

    #include <iostream> #include <stdlib.h> #include <time.h> #include <fstream> ...

  2. Linux 驱动——Button驱动3(poll机制)

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  3. 解决tomcat同时部署两个SpringBoot应用提示InstanceAlreadyExistsException

    问题描述:Caused by: javax.management.InstanceAlreadyExistsException: com.alibaba.druid.pool:name=primary ...

  4. 使用axios获取本地json数据

    1. 通过搜索 网上说不放在static文件夹中会报错  但是一直报错  放到根目录下的时候不报错了 2. 在main.js中引入axios import axios from 'axios' 3. ...

  5. 3.14 unittest之skip

    3.14 unittest之skip 前言当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例.或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用 ...

  6. Java 8 Lambda 表达式(二)

    lambdas 实现 Runnable 接口 下面是使用 lambdas 来实现 Runnable 接口的示例: // 1.1使用匿名内部类 new Thread(new Runnable() { @ ...

  7. 尝鲜svnup

    最近有同事折腾了一下svnup的编译,终于可以在Mac OS X和Linux上面编译通过了,仓库在这里:https://github.com/lvzixun/svnup/ svnup这个工具只有一个功 ...

  8. pdf.js 使用实例(app直接预览pdf格式的文档)

    pdf.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件 pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,,一个负责API解析,一个负责 ...

  9. jirba库的使用和好玩的词云

    1.jieba库基本介绍 (1).jieba库概述 jieba是优秀的中文分词第三方库 - 中文文本需要通过分词获得单个的词语         - jieba是优秀的中文分词第三方库,需要额外安装 - ...

  10. 熟悉 JUnit 测试

    2.1 Mooctest 使用心得 web Ide挺方便,就是很慢.mooctest很方便入门软件测试,但是里面的题目还是不多. 2.2 Junit 编写代码经验总结 1.首先要熟悉junit中经常使 ...