Python多线程多进程
一、线程&进程
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。进程是很多资源的集合。
有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
由于每个进程至少要干一件事,所以,一个进程至少有一个线程。当然,像Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂地交替运行,看起来就像同时执行一样。当然,真正地同时执行多线程需要多核CPU才可能实现。线程是最小的执行单元,而进程由至少一个线程组成。
我们在做事情的时候,一个人做是比较慢的,如果多个人一起来做的话,就比较快了,程序也是一样的,我们想运行的速度快一点的话,就得使用多进程,或者多线程,在python里面,多线程被很多人诟病,为什么呢,因为Python的解释器使用了GIL的一个叫全局解释器锁,它不能利用多核CPU,只能运行在一个cpu上面,但是你在运行程序的时候,看起来好像还是在一起运行的,是因为操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。这个叫做上下文切换。
二、多线程,python中的多线程使用theading模块
下面是一个简单多线程
import threading
import time
def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__':
t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
t1.start() #启动线程
t2.start() #启动另一个线程
下面是另一种启动多线程的方式,继承式
import threading
import time
class MyThread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num = num def run(self):#定义每个线程要运行的函数 print("running on number:%s" %self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()
这两种方式没有什么区别,两种写法而已,我个人喜欢用第一种,更简单一些。
线程等待,多线程在运行的时候,每个线程都是独立运行的,不受其他的线程干扰,如果想在哪个线程运行完之后,再做其他操作的话,就得等待它完成,那怎么等待呢,使用join,等待线程结束
import threading
import time
def run():
print('qqq')
time.sleep(1)
print('done!')
lis = []
for i in range(5):
t = threading.Thread(target=run)
lis.append(t)
t.start()
for t in lis:
t.join()
print('over')
守护线程,什么是守护线程呢,就相当于你是一个国王(非守护线程),然后你有很多仆人(守护线程),这些仆人都是为你服务的,一但你死了,那么你的仆人都给你陪葬。
import threading
import time
def run():
print('qqq')
time.sleep(1)
print('done!')
for i in range(5):
t = threading.Thread(target=run)
t.setDaemon(True)
t.start()
print('over')
线程锁,线程锁就是,很多线程一起在操作一个数据的时候,可能会有问题,就要把这个数据加个锁,同一时间只能有一个线程操作这个数据。
import threading
from threading import Lock
num = 0
lock = Lock()#申请一把锁
def run():
global num
lock.acquire()#加锁
num+=1
lock.release()#解锁 lis = []
for i in range(5):
t = threading.Thread(target=run)
t.start()
lis.append(t)
for t in lis:
t.join()
print('over',num)
下面来个简单的爬虫,看下多线程的效果
import threading
import requests,time
urls ={
"baidu":'http://www.baidu.com',
"blog":'http://www.nnzhp.cn',
"besttest":'http://www.besttest.cn',
"taobao":"http://www.taobao.com",
"jd":"http://www.jd.com",
}
def run(name,url):
res = requests.get(url)
with open(name+'.html','w',encoding=res.encoding) as fw:
fw.write(res.text) start_time = time.time()
lis = []
for url in urls:
t = threading.Thread(target=run,args=(url,urls[url]))
t.start()
lis.append(t)
for t in lis:
t.join()
end_time = time.time()
print('run time is %s'%(end_time-start_time)) #下面是单线程的执行时间
# start_time = time.time()
# for url in urls:
# run(url,urls[url])
# end_time = time.time()
# print('run time is %s'%(end_time-start_time))
三、多进程
上面说了Python里面的多线程,是不能利用多核CPU的,如果想利用多核CPU的话,就得使用多进程,python中多进程使用multiprocessing模块。
from multiprocessing import Process
import time
def f(name):
time.sleep(2)
print('hello', name)
p = Process(target=f, args=('niu',))
p.start()
p.join()
Python多线程多进程的更多相关文章
- Python多线程多进程那些事儿看这篇就够了~~
自己以前也写过多线程,发现都是零零碎碎,这篇写写详细点,填一下GIL和Python多线程多进程的坑~ 总结下GIL的坑和python多线程多进程分别应用场景(IO密集.计算密集)以及具体实现的代码模块 ...
- python学习笔记(十六)-Python多线程多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- python多线程/多进程
thread和threading的区别 threading相对与thread是更高级别的线程管理模块 thread和threading模块中的一些属性会有冲突 thread模块拥有的同步原因实际上只有 ...
- 多线程&多进程解析:Python、os、sys、Queue、multiprocessing、threading
当涉及到操作系统的时候,免不了要使用os模块,有时还要用到sys模块. 设计到并行程序,一般开单独的进程,而不是线程,原因是python解释器的全局解释器锁GIL(global interpreter ...
- python多线程,多进程
线程是公用内存,进程内存相互独立 python多线程只能是一个cpu,java可以将多个线程平均分配到其他cpu上 以核为单位,所以GIL(全局锁,保证线程安全,数据被安全读取)最小只能控制一个核,很 ...
- Python多线程和多进程谁更快?
python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很 ...
- 搞定python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
- python多线程、多进程以及GIL
多线程 使用threading模块创建线程 传入一个函数 这种方式是最基本的,即调用threading中的Thread类的构造函数,然后指定参数target=func,再使用返回的Thread的实例调 ...
- python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
随机推荐
- 有趣的js匿名函数写法(function嵌套)
例子没有什么实际意义,只能做为思路参考 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&quo ...
- iOS xcode创建静态库封装自己的SDK及使用
https://www.cnblogs.com/JustForHappy/p/5773039.html 一,静态库和动态库的区别在这里就不说了,个人感觉如果是自己封装提供别人下载的话应该是静态库比较方 ...
- 20145122《JAVA开发环境的熟悉》实验报告
package fib; public class fibonaci { public static void main(String[] args) { Fibonaci(20); } public ...
- Java集合总结(List、Map、Set)
集合的引入 当我们有种需求,需要存储多个元素的结构时,我们前面讲过数组,数组可以存储.但是数组也有它的弊端,使用的时候,必须先定义好长度,也就是数组的长度是固定,不能根据我们的需求自动变长或者变短. ...
- 在linux桌面上显示图标
把应用程序的图标添加到桌面上 左图显示了把应用程序的图标添加到桌面上的两种方法,哪种更好看? 想要把应用程序图标添加到桌面上,请先确保已设置了在桌面上显示图标,方法是: 1.安装gnome-tweak ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树 lca
大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过 故最大生成树 生成以后 再用lca计算树上两点间的距离 (当然防止生成树是一条链,可以用树的重心作为 ...
- [Shiro] - Shiro之进阶
上一个知识点ssm, 哪里需要权限,哪里写注解@RequirePermission就行. 但是,真正项目开发的时候, 这种方式就很有局限性了, 当权限配置关系发生变化, 每次都要修改代码, 编译打包重 ...
- Window下Latex加速编译方法以及西农毕设论文模板推荐
近些日子用Latex写了一遍文章,一共有11页,但是在window下编译需要2分多的时间,使用的是xeletex编译器. 经过查找,得到了以下方法: 如果坚持使用windows下的latex,使用以下 ...
- 【Android实验】组件通信Intent
实验目的 [TOC] 了解使用Intent进行组件通信原理 掌握使用Intent启动Activity的方法 熟悉和掌握Android组件间通信的方式和技巧 实验要求 设计一个主Activity和一个子 ...
- 贪心算法-Best cow line-字典序问题
代码: #include<cstdio> #include<iostream> #include<stdlib.h> #include<string> ...