python基础

进程&线程

  进程是一组资源的集合,运行一个系统就是打开了一个进程,如果同时打开了两个记事本就是开启了两个进程,进程是一个笼统的概念,进程中由线程干活工作,由进程统一管理

  一个进程至少有一个线程,如果没有,进程也就没有了,线程分为主线程,子线程,而主线程负责调度,支配子线程运行,在代码运行时,主线程分配子线程去干活,而主线程分配之后继续执行后面代码,这时需要我们join一个,主线程等待子线程全部运行完之后,再运行后面代码

单线程  系统默认就起好一个进程,也就是起了一个进程,一个线程

import time
# 单线程    时间叠加了,运行速度会变慢
start = time.time()
def run():time.sleep(5)print("over")
run()
run()
end = time.time()
all_time = end - start
print(all_time)

多线程下载网页

# 单线程下载网页
import threading, requests
def downloads(url, file_name):res = requests.get(url)with open(file_name, 'wb') as wf:wf.write(res.content)
url = {'rainbol1': 'https://www.cnblogs.com/RainBol/','rainbol2': 'https://www.cnblogs.com/RainBol/'}
for file_name, url in url.items():t1 = threading.Thread(target=downloads,args=(url, file_name))  # target指定一个线程让它来帮助我执行,args执行target中的参数,只有一个用args=(url,)t1.start()  # t1.start启动一个线程t1.join()  # 等待子线程工作完毕,主线程再继续运行

多线程  一个进程下面有多个线程

# 由于线程分为主线程和子线程,所以我们要考虑他们之间的同步
# 方法1    for循环实现
import threading, time
def run1():time.sleep(5)print("over")
start = time.time()
list1 = []  # 定义一个list
for i in range(20):  # 定义要开启20个线程t1 = threading.Thread(target=run1)t1.start()list1.append(t1)  # 添加一个子线程到列表中
for t1 in list1:  # 主线程走到这一步子线程都在执行time.sleep()方法,如果继续执行就代码就会走完,所以要等待所有子线程全部运行完毕
    t1.join()
end = time.time()
print(end - start)

# 方法2    while循环实现
import threading, time
def run1():time.sleep(5)print("over")
start = time.time()
for j in range(20):  # 定义要开启20个线程t1 = threading.Thread(target=run1)t1.start()
while threading.activeCount() != 1:  # 如果只有一个线程的时候说明只有一个主线程了,此时循环结束,执行后面代码,否则继续循环pass
end = time.time()
print(end - start)

# 方式3
class Mythread(threading.Thread):def run(self):#方法必须叫runtime.sleep(5)print("over")
for k in range(20):res = Mythread()res.start()#调用必须叫start

守护线程

  如果你想等待子线程完成再退出,那就什么都不用写,或者显示地调用thread.setDaemon(False),设置daemon的值为false。新的子线程会继承父线程的daemon标志。整个Python会在所有的非守护线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。

import time,threading
#守护线程
def shouhu():time.sleep(5)print("555")
for l in range(10):res = threading.Thread(target=shouhu)res.setDaemon(True)#定义守护线程,当定义了这句话表示开启守护线程
    res.start()
print("守护线程结束")

  多个线程同时操作同一个数据的时候一定要加锁

import threading# 锁,记得加锁完一定要解锁,不然出现死锁现象
num = 0
lock = threading.Lock()  # 实例化一把锁
def aaa():global numlock.acquire()  # 加锁num += 1lock.release()  # 解锁 #或者两者一样#with lock:    #num +=1
for i in range(100):t = threading.Thread(target=aaa)t.start()
while threading.activeCount() != 1:pass
print(num)在python2中一定要加锁,python3中会自动加锁解锁,但是为了规范还是加上比较好

多进程  多个进程,每个进程下面只有一个线程工作

  狭隘的来说进程是根据计算机的cpu颗粒数来算的,我们通常做性能测试可以模拟1000个线程,那是cpu在做上下文切换,实际上4核cpu也就是同时只能运行4个线程,我们肉眼根本看不出来误以为计算机开了1000个并发.所以说使用进程的多少取决于你使用的cpu

  而python在语言设计上由于GIL全局解释器锁,只能用cpu的一个核心来处理https://www.cnblogs.com/stubborn412/p/4033651.html

  为什么时候用多进程什么时候用多线程:

  cpu密集型任务(循环处理,计数,运算等):多进程可以利用多核cpu,多启动一个进程下一个线程工作,可以大大提交cpu的处理速度,而多线程来回切换极大消耗cpu的资源

  IO密集型任务(网络爬虫,文件处理等):多线程可以充分利用等待时间,利用其它线程执行代码,而多进程也就是单线程进行IO操作只会傻傻等待

from multiprocessing import Process
import time
def run():time.sleep(50)print("Zzzzz")
if __name__ == '__main__':for i in range(8):  # 启动两个进程p = Process(target=run)p.start()

多进程&多线程应用

from multiprocessing import Process,Manager  #Manager.dict()可以多进程之间共享数据
import threading
import time
def run_threading():time.sleep(60)print("Zzzzz---%s" % threading.current_thread())  # 打印线程名称
def xiancheng():for j in range(10):  # 启动10个线程p = threading.Thread(target=run_threading)p.start()
if __name__ == '__main__':for i in range(10):  # 启动10个进程p = Process(target=xiancheng)p.start()

  10个为子进程,1一个为主进程,一个为pycharm进程

requests

import requests
import nnlog
class MyRequest:log_file_name  = 'MyRequest.log'#日子文件名time_out = 10 #请求超时时间def __init__(self,url,data=None,headers=None,file=None):self.url = urlself.data = dataself.headers = headersself.file = filedef post(self):try:req = requests.post(self.url,data=self.data,headers=self.headers,files=self.file,timeout=self.time_out)except Exception as e:res = {"status":0,"err_msg":e.args}  #0代表请求失败else:try:res = {"status":1,"data":req.json()} #1代表返回的jsonexcept Exception as e:res = {"staus":2,"data":req.text} #2代表返回不是jsonlog_str = 'url: %s 请求方式:post  data:%s ,返回数据:%s'%(self.url,self.data,res)self.write_log(log_str)return resdef get(self):try:req = requests.get(self.url,params=self.data,headers=self.headers,timeout=self.time_out)except Exception as e:res = {"status":0,"err_msg":e.args}  #0代表请求失败else:try:res = {"status":1,"data":req.json()} #1代表返回的jsonexcept Exception as e:res = {"staus":2,"data":req.text} #2代表返回不是jsonlog_str = 'url: %s get请求 data:%s ,返回数据:%s'%(self.url,self.data,res)self.write_log(log_str)return res@classmethoddef write_log(cls,content):log = nnlog.Logger(cls.log_file_name)log.debug(content)

#ThreadPoolExecutor线程池的submit
import time
import requests
from concurrent.futures import ThreadPoolExecutor, waitdef time_ji(fuc):def wrapping(*args, **kwargs):start = time.time()fuc(*args, **kwargs)res = time.time() - startprint(res)returnreturn wrapping
hread = ThreadPoolExecutor(max_workers=2)
page = [x for x in range(1, 6)]
urls01 = ['http://rainbol.cn?page=%s' % i for i in page]
urls01.append('http://www.baidu.com')
list01 = []
@time_ji
def run(i):res = requests.get(i)print(i, str(len(res.text)) + '字节')
for i in urls01:result_submit = thread.submit(run,i)list01.append(result_submit)
wait(list01)  # 等待其他线程工作完成后再执行下面操作
print('都执行完了')
#submit:
# http://rainbol.cn?page=1 35489字节
# 0.07800006866455078
# http://rainbol.cn?page=2 35712字节
# 0.12480020523071289
# http://rainbol.cn?page=3 35534字节
# 0.07800030708312988
# http://rainbol.cn?page=4 35495字节
# 0.06240034103393555
# http://www.baidu.com 2381字节
# 0.14039993286132812
# http://rainbol.cn?page=5 25010字节
# 0.32760047912597656

#ThreadPoolExecutor线程池的submit
import time
def time_ji(fuc):def wrapping(*args, **kwargs):start = time.time()fuc(*args, **kwargs)res = time.time() - startprint(res)returnreturn wrapping
import requests
from concurrent.futures import ThreadPoolExecutor, wait
thread = ThreadPoolExecutor(max_workers=2)
page = [x for x in range(1, 6)]
urls01 = ['http://rainbol.cn?page=%s' % i for i in page]
urls01.append('http://www.baidu.com')
list01 = []
@time_ji
def run(i):res = requests.get(i)print(i, str(len(res.text)) + '字节')
result_map = list(thread.map(run, urls01))
print('都执行完了')
#http://rainbol.cn?page=2 35712字节
#0.09200549125671387
#http://rainbol.cn?page=1 35489字节
#0.12100696563720703
#http://rainbol.cn?page=3 35534字节
#0.08300471305847168
#http://rainbol.cn?page=4 35495字节
#0.10100579261779785
#http://www.baidu.com 2381字节
#0.06100344657897949
#http://rainbol.cn?page=5 25010字节
#0.28101587295532227
#都执行完了#ProcessPoolExecutor进程
from concurrent.futures import ProcessPoolExecutor, wait
import time
import requests
page = [x for x in range(1, 6)]
urls01 = ['http://rainbol.cn?page=%s' % i for i in page]
urls01.append('http://www.baidu.com')
def run(i):start = time.time()res = requests.get(i)print(i, str(len(res.text)) + '字节')print(time.time()-start )
process1 = ProcessPoolExecutor(max_workers=2)
if __name__ == '__main__':  #必须加main不然会报错list01 = []for i in urls01:result_map = process1.submit(run, i)list01.append(result_map)wait(list01)print('都执行完了')

http://rainbol.cn?page=1 35489字节
0.08200478553771973
http://rainbol.cn?page=2 35712字节
0.10700583457946777
http://rainbol.cn?page=3 35534字节
0.09300518035888672
http://rainbol.cn?page=4 35495字节
0.08600473403930664
http://rainbol.cn?page=5 25010字节
0.06000328063964844
http://www.baidu.com 2381字节
0.06800413131713867
都执行完了

版权声明:本文原创发表于 博客园,作者为 RainBol 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

转载于:https://www.cnblogs.com/RainBol/p/9980099.html

python学习之多线程多进程相关推荐

  1. python学习笔记——多线程编程

    python学习笔记--多线程编程 基础不必多讲,还是直接进入python. Python代码代码的执行由python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时 ...

  2. python 学习总结2 多进程与协程

    多进程: 我们什么时候需要多进程呢?我们知道python的多线程,实际不是真实的多线程,它同一时间在一个cpu执行一个任务,它通过上下文的切换来让我看起来是多并发的, 那么如果我们想要真正实现多个任务 ...

  3. 【python学习】多线程下载图片实战

    python多线程下载图片(setu) 前言 python的学习其实早在两三个星期前就开始了,奈何我是个急性子,所以学的很浮躁,甚至连md笔记都没写.但是想了想,我学python的目的反正也仅仅是为了 ...

  4. python学习笔记(二十三) -- 多进程和多线程

    目录 多线程多进程的意义 多进程的使用 方式一(fork):  只能在Unix/Linux/Mac系统下执行,windows不可以 方式二(multiprocessing.Process): 全平台通 ...

  5. python学习笔记(十六)-Python多线程多进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  6. python爬虫用多线程还是多进程_python爬虫之多线程、多进程爬虫

    多线程对爬虫的效率提高是非凡的,当我们使用python的多线程有几点是需要我们知道的: countdown是一个计数的方法,正常执行它,我们一般使用countdown(10),就可以达到执行的目的,当 ...

  7. Python 学习笔记 多进程 multiprocessing

    Python 解释器有一个全局解释器锁(PIL),导致每个 Python 进程中最多同时运行一个线程,因此 Python 多线程程序并不能改善程序性能,不能发挥多核系统的优势,可以通过这篇文章了解. ...

  8. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪 ...

  9. python web框架 多线程和多进程_python的多线程和多进程(一)

    在进入主题之前,我们先学习一下并发和并行的概念: --并发:在操作系统中,并发是指一个时间段中有几个程序都处于启动到运行完毕之间,且这几个程序都是在同一个处理机上运行.但任一时刻点上只有一个程序在处理 ...

  10. python爬虫之多线程threading、多进程multiprocessing、协程aiohttp 批量下载图片

    一.单线程常规下载 常规单线程执行脚本爬取壁纸图片,只爬取一页的图片. import datetime import re import requests from bs4 import Beauti ...

最新文章

  1. 字节一面,被连问 MySQL 索引,脸都问绿了。。。
  2. UUID,加密解密算法的使用
  3. [剑指offer][JAVA]面试题[第23题][合并K个排序链表][分治][优先队列]
  4. CCF201604-2 俄罗斯方块
  5. 力扣53.最大子序和 多种方法
  6. react-native与原生三种交互模式
  7. ​8次迭代5大升级,旷视天元1.0预览版正式发布
  8. 判断Mouse事件源类型
  9. PSP游戏下载地址大全
  10. ppm与LSB含义,换算
  11. win10下Google Chrome 打不开网页的解决方案
  12. 关于桌面文件,软件图标,带蓝底白问号的解决方法
  13. 计算机毕业设计ssm线上学习系统8e88w系统+程序+源码+lw+远程部署
  14. Vue 前端框架接入QQ在线客服
  15. IntelliJ IDEA中项目的包和目录结构显示设置
  16. Django 2.1.7 项目技巧 - 创建apps应用目录归纳所有应用
  17. 题解-hzy loves segment tree I
  18. Hadoop之——计算机网络端口的定义
  19. https攻击工具详解(arp欺骗、中间人攻击)(openssl+sslscan+sslsplit )
  20. 如何彻底删除ELTIMA的vspd(虚拟串口)

热门文章

  1. fibonacci数列python_从 Python 计算 Fibonacci 数列说起
  2. 目标检测(六)--SPPNet
  3. 双目测距(四)--罗德里格斯变换
  4. 2022年考研计算机组成原理_5 中央处理器
  5. 大学c语言作业网站,西北农林科技大学c语言作业
  6. MCU —— 数码管显示笔记
  7. 如何在不接收返回值的情况下获取返回值?
  8. 关于二进制兼容(二进制边界)的解释
  9. 30-40岁的程序员们,请把一些账算清楚,为过冬做准备(一)
  10. Uncaught TypeError: Cannot read property 'tagNa...