多线程

python的多线程、多进程、协程用代码详解

醉酒当歌 提交于 2020-04-06 16:39:40
前言 文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 作者:刘早起早起 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http://t.cn/A6Zvjdun 很多时候我们写了一个爬虫,实现了需求后会发现了很多值得改进的地方,其中很重要的一点就是爬取速度。本文就通过代码讲解如何使用 多进程、多线程、协程 来提升爬取速度。注意:我们不深入介绍理论和原理,一切都在代码中。 同步 首先我们写一个简化的爬虫,对各个功能细分,有意识进行函数式编程。下面代码的目的是访问300次百度页面并返回状态码,其中parse_1函数可以设定循环次数,每次循环将当前循环数(从0开始)和url传入parse_2函数。 性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待 示例代码就是典型的串行逻辑,parse_1将url和循环数传递给parse_2,parse_2请求并返回状态码后parse_1继续迭代一次,重复之前步骤 多线程 因为CPU在执行程序时每个时间刻度上只会存在一个线程,因此多线程实际上提高了进程的使用率从而提高了CPU的使用率 实现多线程的库有很多,这里用concurrent.futures中的ThreadPoolExecutor来演示

Python并发编程之多线程使用

瘦欲@ 提交于 2020-04-06 11:34:24
目录 一 开启线程的两种方式 二 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别 三 练习 四 线程相关的其他方法 五 守护线程 六 Python GIL(Global Interpreter Lock) 七 同步锁 八 死锁现象与递归锁 九 信号量Semaphore 十 Event 十一 条件Condition(了解) 十二 定时器 十三 线程queue 十四 Python标准模块--concurrent.futures 一 开启线程的两种方式 ``` #方式一 from threading import Thread import time def sayhi(name): time.sleep(2) print('%s say hello' %name) if name == ' main ': t=Thread(target=sayhi,args=('egon',)) t.start() print('主线程') 方式二 from threading import Thread import time class Sayhi(Thread): def init (self,name): super(). init () self.name=name def run(self): time.sleep(2) print('%s say hello' % self

并发编程-多线程,GIL锁

倾然丶 夕夏残阳落幕 提交于 2020-04-06 11:32:00
本章内容: 1.什么是GIL 2.GIL带来的问题 3.为什么需要GIL 4.关于GIL的性能讨论 5.自定义的线程互斥锁与GIL的区别 6.线程池与进程池 7.同步异步,阻塞非阻塞 一.什么是GIL 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) ''' 释义: 在CPython中,这个全局解释器锁,也称为GIL,是一个互斥锁,防止多个线程在同一时间执行Python字节码,这个锁是非常重要的,因为CPython的内存管理非线程安全的,很多其他的特性依赖于GIL,所以即使它影响了程序效率也无法将其直接去除 总结: 在CPython中,GIL会把线程的并行变成串行

多线程 CountDownLatch

霸气de小男生 提交于 2020-04-06 02:56:02
import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * 闭锁 * https://www.cnblogs.com/takumicx/p/9698867.html */ public class CountDownLatchTest { private static CountDownLatch countDownLatch; public static void main(String[] args) throws InterruptedException { int count = 10; // 初始化计数器值为10 countDownLatch = new CountDownLatch(count); // 开启10个子线程执行子任务 for (int i = 0; i < count; i++) { Thread thread = new Thread(new CountDownThread(countDownLatch, i)); thread.start(); } // 主线程等待,直到所有子任务完成 countDownLatch.await(); // 模拟主线程执行后续工作 TimeUnit.SECONDS.sleep(1); System.out

多线程 FutureTask、Future、Callable

跟風遠走 提交于 2020-04-06 02:47:38
1、Future import lombok.extern.slf4j.Slf4j; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @Slf4j public class FutureExample { static class MyCallable implements Callable<String> { @Override public String call() throws Exception { log.info("do something in callable"); Thread.sleep(5000); return "Done"; } } public static void main(String[] args) throws Exception { ExecutorService executorService = Executors.newCachedThreadPool(); Future<String> future = executorService.submit(new

多线程 CyclicBarrier

心已入冬 提交于 2020-04-06 02:40:44
import java.util.concurrent.CyclicBarrier; /** * 循环屏障 */ public class CyclicBarrierTest { static CyclicBarrier cyclicBarrier; public static void main(String[] args) { int count = 10; // 当所有子任务都执行完毕时,barrierAction的run方法会被调用 cyclicBarrier = new CyclicBarrier(count, () -> System.out.println("执行barrierAction操作!")); // 开启多个线程执行子任务 for (int i = 0; i < count; i++) { new Thread(new CyclicBarrierThread(cyclicBarrier, i)).start(); } } private static class CyclicBarrierThread implements Runnable { public CyclicBarrier cyclicBarrier; // 任务序号 public int taskNum; public CyclicBarrierThread(CyclicBarrier

多线程

自作多情 提交于 2020-04-05 18:10:08
进程vs线程: 进程:每个程序被运行加载到内存之后,都会被操作系统作为一个进程,进程是处于运行过程中的程序,是具有独立功能,被操作系统进行资源分配和调度的独立单元。 线程:一个进程里面可以拥有多个线程,线程拥有自己的堆栈,程序计数器和自己的局部变量,但是不拥有系统资源,多个线程共享进程的系统资源。 创建线程的三种方式: 1.继承Thread类创建线程类 继承Thread类,重写run()方法,该run()方法就代表程序需要完成的任务。创建Thread子类的实例,即创建线程对象。然后通过start()方法启动线程。 1 public class MyThread extends Thread { 2 private int count; 3 4 @Override 5 public void run() { 6 7 for (; count < 100; count ++) { 8 System.out.println(getName() + "---" + count); 9 } 10 } 11 12 public static void main(String[] args) { 13 for (int i = 0; i < 100; i++) { 14 System.out.println(Thread.currentThread().getName() + i); 15 if

【Python3 爬虫】U28_多线程爬取斗图啦的表情包

谁都会走 提交于 2020-04-05 17:12:00
目录 1.需求描述 2.实战代码 2.1 单线程爬取 2.2 多线程版 1.需求描述 爬取斗图啦网站,地址为: https://www.doutula.com/photo/list/ ,网站截图如下: 现在需要按页爬取前2页的表情包,那么接下来直接上代码吧。 2.实战代码 2.1 单线程爬取 from urllib import request import requests from lxml import etree import re import os HEADERS= { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36' } def parse_url(url): response = requests.get(url, headers=HEADERS) text = response.text html_str = etree.HTML(text) imgs = html_str.xpath('//div[@class="page-content text-center"]//a/img[@class!="gif"]') for img in imgs: img

java多线程

旧城冷巷雨未停 提交于 2020-04-04 06:16:05
1、进程与线程 我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程(Thread)。 线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。 当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。 同步这个词是从英文synchronize(使同时发生)翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用,咱们也就只好这么将就。 线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作 。 因此,关于线程同步,需要牢牢记住的第一点是: 线程同步就是线程排队 。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。 关于线程同步,需要牢牢记住的第二点是 “共享” 这两个字。 只有共享资源的读写访问才需要同步 。如果不是共享资源,那么就根本没有同步的必要。 关于线程同步,需要牢牢记住的第三点是,只有“ 变量 ”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。

OC开发_整理笔记——多线程之GCD

泄露秘密 提交于 2020-04-03 10:22:10
一、进程和线程     二、各种队列!   1、GCD:Grand Central Dispatch   2、串行队列(Serial)     你 可以创建 任意个数的串行队列,每个队列依次执行添加的任务, 一个队列同一时刻只能执行一个任务 (串行),但是各个队列之间不影响,可以并发执行。每个队列中的任务运行在一个由各自串行队列    维护的独立线程上, 一个队列中只有一个线程 。   3、并行队列(Concurrent)     并行队列是 不允许自己创建 的,系统中存在三个不同优先级的并行队列。并行队列依旧按照任务添加的顺序启动任务,但是,后一个任务无须等待前一个任务执行完毕,而是启动第一个任务后,立即启动    下一个任务。至于同一时刻允许同时运行多少个任务由 系统决定 。任务各自运行在并行队列为他们提供的独立线程上, 并行队列中同时运行多少个任务,就必须维护多少个线程 。   4、主调度队列(main dispatch queue)     主调度队列中的任务运行在应用程序 主线程 上,所以,如果你要修改应用程序的界面,他是唯一的选择   5、全局队列(苹果为了方便多线程的设计,提供一个全局队列,供 所有的APP共同使用 ) 三、队列的任务处理   1、串行队列(✅ DISPATCH_QUEUE_SERIAL )的同步任务和异步任务:dispatch_sync 和