-
Python学习----多线程处理工作队列
2017-09-21 19:24:03目标开始学习Python,练手 建立一个任务队列,添加一堆任务,然后开启多个... MyWorkThread.workQueue.put(work)#启动多线程,处理工作队列里的内容 threads = [] for i in range(THREAD_NUM): thread = MyWorkThr目标
开始学习Python,练手
建立一个任务队列,添加一堆任务,然后开启多个线程去处理队列里的任务代码
#创建工作队列 for i in range(100000): MyWorkThread.workQueue.put(work)
#启动多线程,处理工作队列里的内容 threads = [] for i in range(THREAD_NUM): thread = MyWorkThread.MyWorkThread() thread.start() threads.append(thread) #等待队列清空 while not MyWorkThread.workQueue.empty(): time.sleep(2) pass #MyWorkThread.workQueue.join() #通知线程是时候退出 MyWorkThread.exitAllThread() print('触发退出所有工作线程') #等待所有线程完成退出 for t in threads: t.join()
#!/usr/bin/python #coding=utf-8 import threading import time import traceback import os import Queue class MyWorkThread(threading.Thread): def __init__(self,): threading.Thread.__init__(self) def run(self): global workQueue global exitFlag globalLock.acquire() loop = exitFlag globalLock.release() while not loop: try: #任务并运行 work = workQueue.get(False) work.run() del work except Queue.Empty: time.sleep(0.5) except Exception as e: print('ERROR:',e) print('traceback.format_exc():\n%s' % traceback.format_exc()) time.sleep(0.5) os._exit(0) globalLock.acquire() loop = exitFlag globalLock.release() print('线程{}结束'.format(self.tid)) def exitAllThread(): global exitFlag globalLock.acquire() exitFlag=1 globalLock.release() workQueue = Queue.Queue() #工作队列 globalLock = threading.Lock() #全局变量锁 exitFlag = 0 #线程结束
-
使用多线程处理耗时工作
2013-04-29 18:24:13大家对多线程处理耗时工作的重要性应该早已认识到。本章的关键点是:把耗时的、与UI渲染无关的操作进行分割分配到多个线程中并发执行。 在本章,googler 全篇介绍了通过 java 线程池来构造多线程执行环境的...大家对多线程处理耗时工作的重要性应该早已认识到。本章的关键点是:把耗时的、与UI渲染无关的操作进行分割分配到多个线程中并发执行。
在本章,googler 全篇介绍了通过 java 线程池来构造多线程执行环境的详细流程,关键要点如下:
1. 定义一个能在 Thread 中执行的 Runnable 子类 SubRunnable,把耗时的工作交给 SubRunnable 的 run() 方法;
2. 在 run() 中通过 Thread.currentThread() 获取并保存SubRunnable 所在的线程以备中断所需;
3. 初始化一个 BlockingQueue<Runnable> 队列的实例runQueue,用于排队缓冲等待执行的 SubRunnables;
4. 初始化并配置一个 java 线程池 ThreadPoolExecutor的实例 threadpool,配置初始化可用线程数、最大可用线程数、线程关闭前的闲置时间、闲置时间单位、工作队列(即上述初始化的 runQueue);
5. threadpool 是 runQueue 的实际操纵者,负责将 SubRunnable 排队、按照FIFO策略给 SubRunnable 分配 Thread 并调度执行;
6. 构造一个 Handler 的实例 mainHandler 用于接收 SubRunnable 执行的状态和结果,并更新UI,所以必须用主线程Looper 来初始化它:mainHandler= new Handler(Looper.getMainLooper()); 这样 mainHandler 将与 mian Looper 同处于主线程中,可以接收主线程的派发事件;
7. 当需要提交新的任务执行时,调用 threadpool.execute(newRunnable); newRunnable 将被排队调度执行;
8. 当 SubRunnable 需要报告执行状态和结果时,通过 mainHandler 传送给 UI 线程处理;
9. 当 SubRunnable 执行完毕,确定不再需要它时,中断其所在线程,并将其从队列中移除:”the runnable’s thread”.interrupt(); threadpool.remove(“the runnable”);这点很重要,否则队列中的资源无法释放,严重时将抛出 RejectedExecutionHandler 异常。
实际上这是一个android.os.AsyncTask 的手动实现流程,android.os.AsyncTask 正是对此流程的一种封装,只是不过手动实现的方案有更大的弹性,你可以灵活地配置 ThreadPoolExecutor 的参数和队列。
如果大家有兴趣可以查看一下android.os.AsyncTask 的源代码:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/os/AsyncTask.java#AsyncTask
下面通过图示简要总结一下以上流程:
-
多线程处理大文件_工作中没有多线程使用场景,怎么办
2020-12-10 07:31:48另外,在几乎所有的 Java 岗位的招聘要求中,都会提到多线程,如果你不能针对多线程说出个一二三,恐怕都找不到满意的工作。但是,很多同学在工作过程中,好像并不会接触到多线程的东西啊。我们知道,像 tomcat 这种...网上的各种关于 Java 学习路线的文章中都会提到多线程,往往作为 Java 进阶的部分存在。就是说当你想要在 Java 这条路上有所成,必须要掌握多线程。另外,在几乎所有的 Java 岗位的招聘要求中,都会提到多线程,如果你不能针对多线程说出个一二三,恐怕都找不到满意的工作。
但是,很多同学在工作过程中,好像并不会接触到多线程的东西啊。我们知道,像 tomcat 这种服务器软件本身就是多线程的,但是人家都已经封装好了,我们只需要拿来用即可,并不需要我们对多线程进行什么特殊的操作。
其实大多数的同学并不会直接在工作中使用多线程开发。那怎么办呢,我们总不能为了使用多线程而使用多线程吧。
那么什么场景下会使用到多线程技术呢。
多线程的使用场景
1、应用服务器软件
各种服务器软件都支持多线程的,比如我们常用的 Tomcat、Nginx、Jetty 等。因为线上服务肯定都不是一个人使用的,只要有多人访问,就有可能出现并发的情况,所以服务端软件必须是支持多线程的。
对于这些服务器软件,我们平时就是当做黑盒使用,最多也就是定制一下参数。很少有人有机会参与修改和开发。
2、游戏后端服务
如果你是从事游戏服务端开发的,游戏服务器一般都是定制开发的,我们的应用程序大多数都是 HTTP、HTTPS 协议,而游戏是一个长交互的过程,所以游戏中采用的通信协议一般都是 TCP、UDP 协议,如果是页游的话则可能是 websockets。而且游戏一般都是多人同时在线,必须要支持多线程、高并发。而且大多数的游戏后端服务都是采用 C++ 开发,很少有用 Java 开发的。
3、中间件、框架
中间件类似于连接器的效果,比如数据库中间件,用来连接我们的应用服务和数据库集群。
框架指的是那些封装好的拿来即用的框架,比如 RPC 框架,例如 Dubbo。或者是高性能的服务器框架 Netty。
由于面向的使用者未知,有可能是只有几十个人的内部应用,也有可能是成百上千万的超级应用,所以必须要考虑高并发、多线程的情况。
只有极少数的人需要开发中间件或者好用的框架,大多数人没有这个机会。
4、后台离线任务
后台离线任务一般是定期执行的 job,比如对于实时性要求不高的报表进行统计。
比如一个文件系统,每天要统计文件的增量信息,比如新增文件个数、文件空间占用等,我们如果用单一线程统计的话,当天新增文件较多的情况下统计就会很慢,这种情况就可以使用多线程统计,如果文件本身按照一定的规则分放的不同的文件夹里,可以针对每个文件夹创建一个线程进行扫描。
或者对于 mysql 数据表进行统计,比如对多个表进行汇总,每个表作为一个汇总指标存在,这样就可以针对每个表创建一个线程处理。或者有分库分表的情况,可以针对每个分表开启一个线程处理。
以上这些离线任务都可以通过多线程的方式加快处理速度。而这个场景在我们的项目中碰到的几率也比较大。
5、异步处理任务
异步处理任务类似于离线任务,同样是对实时性要求不是很高的情况下。比如电商系统中经常用到的短信、邮件通知的情况,用户在某电商网站下单付款后,通常会收到短信或者邮件的通知,而通知信息对于整个购买环节并不是最重要的,商家最关心的就是减掉库存和收到付款,所以对于通知的发送一般都采用异步方式,允许一定的延时甚至发送失败的情况。
当用户购买商品成功后,系统会向消息队列中写入订单相关的信息,发送通知的异步任务去消息队列拉取消息,拉到一个订单就向对应的手机或者邮箱发送通知消息。而这里的发送通知任务一般都采用多线程的方式,用来提高并发度,减小用户下单成功到收到通知之间的延时。
类似的场景都可以采用多线程的异步任务去处理,而我们在项目中碰到这种场景的几率也不小。
6、天然需要多线程的
另外还有一些功能就是一想到自然就想到多线程的情况,比较明显的就是爬虫程序。
通过爬虫学习多线程
如果你想学习多线程开发,但是又找不到合适的学习场景(对于照着书本或者博客敲一些 demo 代码并不能很好的掌握多线程开发),那么你可以试着写个爬虫玩玩,既有趣儿又可以学习,何乐而不为呢。
当然一提到写爬虫,大家可能最先想到的是 Python,没错,比如我在刚学习 Python 的前两年就热衷于写爬虫,比如 2014 年写的这篇 https://www.cnblogs.com/fengzheng/p/3913639.html ,抓取百度音乐,竟然还用 PYQT 做了个界面出来,也真是有耐心。
今天建议大家写爬虫来学习 Java 多线程,那就自然是用 Java 开发了。
这里只说单机多线程的爬虫,不包括分布式爬虫。
一般用爬虫就是需要大批量数据的场景,比如说抓取某个或某些微博大 V 的微博内容,比如抓取知乎回答,豆瓣电影排行信息,甚至到 PornHub 上抓一下 Python 教程来学一学也是可以的。
拿微博来说吧,比如我准备采集某领域的 100 个大 V 的微博内容,如果用单线程来爬,可能耗时几十分钟,甚至几个小时。如果是更大量的数据采集,那耗时可想而知了。
为了加快速度、提高效率,一般都会采用多线程的方式来爬取数据。
不仅如此,爬虫程序还是生产消费者模式的经典应用场景。
整体的逻辑如下:
1、多个线程(这里的线程也就是生产消费者模式中的生成者线程)到目标网站上抓数据;
2、然后将数据放到一个中间队列,有条件的可以弄个真正的消息队列,比如 RabbitMQ、RocketMQ、kafka 或者 redis 也可以,没有条件的用 Java 本身的队列 Queue 也可以,或者自己实现一个队列结构;
3、最后,多个消费者线程订阅中间队列,将数据加工处理后存入数据库或者写入文件,实现持久化。
涉及到多线程的知识点
线程的创建
爬虫生产者线程和消费线程的创建,可以采用线程创建的两种方式:
1、实现 Runnable 接口,并重写 run() 方法
public static void main( String[] args ){
ProducerWorker producerWorker = new ProducerWorker();
producerWorker.run();
}
public static class ProducerWorker implements Runnable {
@Override
public void run(){
try {
/* 抓取数据 */
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
-
python 多线程处理数据_Python多线程与多处理
2021-01-28 20:58:14Python多线程与多处理Python中有一个称为线程的库 ,它使用线程(而不只是进程)来实现并行性。如果您了解Python的Global Interpreter Lock或GIL,这可能是令人惊讶的消息 ,但是它实际上在某些情况下可以很好地工作而...Python多线程与多处理
Python中有一个称为线程的库 ,它使用线程(而不只是进程)来实现并行性。如果您了解Python的Global Interpreter Lock或GIL,这可能是令人惊讶的消息 ,但是它实际上在某些情况下可以很好地工作而不会违反GIL。这一切都没有任何开销-只需定义发出I / O请求的功能,系统即可处理其余的功能。
全局翻译锁
全局解释器锁通过一次只允许一个本机线程执行,从而降低了Python(更确切地说是CPython)中线程的有用性 。这使得在(通常是线程不安全的)C库中实现Python更加容易实现,并且可以提高单线程程序的执行速度。但是,它仍然存在争议,因为它阻止了真正的轻量级并行性。您可以实现并行性,但是它需要使用多重处理,这由同名的库 multiprocessing实现。该库不使用线程,而是使用绕过GIL的进程。
看起来,GIL会杀死Python多线程,但效果不佳。通常,多线程有两个主要用例:
在单台计算机上利用多个内核
利用I / O延迟来处理其他线程
通常,我们不能从(1)的线程中受益,但可以从(2)的中受益。
多处理
通用 threading 库是相当低级的,但事实证明它是将其 multiprocessing 包装起来的 multiprocessing.pool.ThreadPool,它方便地采用与相同的接口 multiprocessing.pool.Pool。
使用的好处之一 threading 是可以避免酸洗。多处理依赖于内存中的酸洗对象将其发送到其他进程。例如,如果 timed 装饰没有 wraps 了 wrapper 它返回的函数,那么CPython中就能够咸菜我们的功能 request_func ,并 selenium_func 因此这些不能多处理。相比之下,该 threading 库即使通过 multiprocessing.pool.ThreadPool 工作也很好。多处理还需要更多的内存和启动开销。
分析
我们分析了高度依赖I / O的任务,即对随机的维基百科页面发出100个URL请求。我们比较一下:
Python 请求 模块和
带有 PhantomJS的Python 硒。
我们以三种方式运行这些请求,并测量每次获取所需的时间:
串联
在threading 具有10个线程的池中并行
在multiprocessing 具有10个线程的池中并行
每个请求都是定时的,我们比较结果。
结果
首先,for的每线程运行时间 requests 明显少于for selenium,因为后者需要启动一个新进程来运行 PhantomJS 无头浏览器。还有趣的是,各个线程(尤其是硒线程)的串行运行速度比并行运行速度快,这是典型的带宽与延迟之间的权衡。
尤其是,硒线程的速度要慢两倍以上,这很可能是由于10个硒工艺一次旋转导致的资源争夺。
同样, 与串行相比,多线程时所有线程的selenium 请求运行速度大约快4倍,请求运行速度 大约快8倍 requests。
结论
使用threading 和 之间没有明显的性能差异 multiprocessing。多线程和多处理之间的性能极为相似,确切的性能细节可能取决于您的特定应用程序。穿线 multiprocessing.pool.ThreadPool 真的很容易,或者至少和使用multiprocessing.pool.Pool 界面一样容易 -只需将I / O工作负载定义为一个函数,然后使用 ThreadPool 即可并行运行它们。
1
-
GraphicsMagick在多线程环境工作时其自身多线程处理会变成单线程
2013-05-28 14:08:03随后改变OMP_NUM_THREADS的数目对以上测试结果没有影响,也就是说GM自身多线程处理图片在多线程环境中其实是无效的。 使用多进程测试: 使用的GM的C core API,在多进程环境下处理图片CPU利用率可以根据环境... -
wpf 多线程处理同步数据_Redis 6.0 多线程IO处理过程详解
2020-10-21 21:58:43本文将深入到实处,内容包含:介绍Redis单线程IO处理过程单线程的问题解析Redis多线程IO如何工作要分析多线程IO,必须先搞清楚经典的单线程异步IO。文章会先介绍单线程IO的知识,然后再引出多线程IO,如果已经熟悉,... -
python多线程处理循环方式_使用python循环的多线程处理
2021-01-14 11:56:27我试图在处理器的几个线程上运行这个Python代码,但是我找不到如何分配多个线程。我在Jupyter(以前叫I python)中使用的是python 2.7。初始代码如下(所有这部分都...不带多线程的代码my_list = ['http://stackover... -
python多线程处理文件安全_Python多线程文件处理
2020-12-17 00:14:53你混淆了两种不同的解决方案。...好吧,第一个显然更简单,但是如果你有,比如说,1000个文件要复制,你最终会创建1000个线程,这比你想创建的线程要多,而且线程数量远远超过操作系统能够处理的并行副... -
详解Java多线程处理List数据
2020-08-26 05:16:24主要介绍了Java多线程处理List数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
异步多线程(五)多线程异常处理
2019-09-28 11:30:42多线程异常处理 概念 多线程里面抛出的异常,会终结当前线程;但是不会影响别的线程;在工作中一般情况下,不仅需要捕获到异常信息,还可能需要 去通知其他线程,这就涉及到另外一个概念线程取消 工作中常规建议... -
java多线程处理
2014-07-29 11:06:45如果在一个进程中同时运行了多个线程,用来完成不同的工作,我们就成为多线程。 主线程就是一个进程的入口。所有一个进程至少包含一个线程,那就是主线程。 线程的特点:1、一个进程可以包含多个线程,而一个线程 -
HTML5 多线程处理
2017-11-14 22:14:00HTML5中我觉得最有用和激动人心的功能就是引入了线程的概念,从而我们可以用多线程的思想来处理比较复杂的应用。我们可以让前台线程去完成和用户交互的工作,而把比较复杂的,耗时较长的运算放在后台线程中完成,而... -
Task多线程(异步多线程处理)(操作百度翻译API接口)
2019-12-02 20:54:42关于异步多线程处理(操作百度翻译API接口) 近期被Task搞到爆炸,本来写的好好的异步操作,提示各种例如“无await异步操作将按照同步来执行”,由于之前我对于多线程基本等于零了解,这次由于工作需要轻轻松松被一... -
多线程处理返回值
2019-09-08 14:43:08好久没写博客,看了下上一篇发表的时间发现已是一年多前,看到消息处的小红点,点了下发现仍然有很多新朋友关注了我,给我留言,给我的博文点赞,让我发现技术分享的重要性,不仅仅是影响一个人,而是影响一群人。... -
多线程并行处理数据
2020-09-01 17:08:08在工作中很多时候会因为各种原因选择使用多线程并行去处理我们要处理的数据,前段时间工作中就遇到了需要多线程去处理的业务逻辑情况,记录一下。 业务场景 在后台系统代码中,首先会拿到一些条件,然后会根据入参... -
多线程处理大数据文件
2014-03-25 17:06:41最近与同事研究一题目:通过多线程处理大数据文件,数据文件大小为1G,文件格式为bin格式(纯文本,utf-8编码方式)。 主要要进行的工作是:通过多线程解析,每一条记录保存到mysql数据库中(查看文件可得500W条数据... -
使用OpenMP进行多线程处理时,如何退出多线程
2015-02-05 14:13:02在最近的工作中,遇到了一种情况,内容如下:在多线程循环中进行并行处理数据,但是当其中一个线程中的一组数据满足于一个特定的条件时,需要将所有线程挂起,并且弹出提示框,并根据用户在提示框中的选 -
关于iOS的多线程处理方式
2015-08-06 16:29:56同一时间,CPU只能处理1条线程,只有1条线程在工作(执行) 多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换) 如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象 思考:如果线程... -
第十八章 多线程处理
2017-09-21 10:04:031、多线程基础 1.1 基本概念 进程:进程是操作系统中的一个基本概念,进程包含了一个程序运行所需的资源,一个进程包含多个线程。线程:线程是进程的基本执行单元,进程入口执行的第一个进程称为主线程。任务:任务... -
python如何使用多线程_如何使用Python多线程处理MySQL连接
2020-11-24 12:28:57我有一个连接到MySQL数据库的主Python...为了达到这个目的,我试着:1.)将数据库连接传递给所有线程2.)从每个线程打开一个新的数据库连接但他们都没有工作。在这两种情况下,我都可以使用try/except运行更新,但M... -
通过多线程处理提高Redis性能
2019-10-05 18:11:53Redis还运行多个后端线程来执行后端清理工作,例如清理脏数据和关闭文件描述符。在Redis中,主线程负责主要任务,包括但不限于:接收来自客户端的连接,处理连接读/写事件,解析请求,处理命令,处理定时器事件和... -
unity3d多线程处理
2013-08-26 11:32:26多线程的工作往往是一种必要的罪恶。这就是我要做的是在一个Unity3D组件安全。当它是安全的时候,读取或更改其他组件的变量。例如,如果你试图修改或查询物理组件,你会遇到问题,同时一FixedUpdate发生了!这个组件... -
多线程中处理线程泄漏
2012-03-28 17:10:23多线程中线程常常会因为抛出RuntimeException终止 考虑如下的场景:一个线程用来接收外部系统的输入(输入线程),当有输入时用调用notify()唤醒另一个输出线程,将输入内容转存到另个的系统里。 当输入线程... -
java 工作流多线程_java多线程
2021-02-26 21:38:361、多线程的意义操作系统可以多任务执行,每个任务就是就是一个进程。每个任务(进程)可以分多工作流分别执行。比较:进程:有独立的代码和数据空间(进程上下文),进程切换开销大,进程是资源分配的最小单位。线程:... -
Linux环境编程--多线程的工作原理以及多线程锁
2018-02-05 13:54:30有了多线程之后,我们可以让一个进程同一时刻做不止一件事,每个线程处理各自独立的任务。 多线程与多进程之间的区别: 1.创建的方式不相同,多进程调用vfork()/fork()进行创建而多线... -
多线程分页处理数据(主线程阻塞直到所有子线程处理完毕并接收返回结果)
2019-09-11 08:55:50备注:将数据分页,以FixedThreadPool(定长线程池)+CountDownLatch(并发流程控制)+Callable(有返回值的多线程) + Future(接收Callable的返回值)的形式进行多线程处理数据。其中CountDownLatch的工作原理:在...
-
基于Qt的LibVLC开发教程
-
MySQL 触发器
-
用微服务spring cloud架构打造物联网云平台
-
‘tf2_ros::TransformListener::TransformListener(tf2::BufferCore&, ros::NodeHandle const&, bool)’未定义..
-
redis-6.0.6-windows.zip
-
自动化测试Python3+Selenium3+Unittest
-
Galera 高可用 MySQL 集群(PXC v5.7+Hapro)
-
基于Flink+Hudi构建企业亿级云上实时数据湖教程(PC、移动、小
-
lock和synchronized区别
-
物联网基础篇:快速玩转MQTT
-
2021年 系统分析师 系列课
-
Django
-
MyBatisSelf.rar
-
Liunx 优化思路与实操步骤
-
项目经理成长之路
-
LVS + Keepalived 实现 MySQL 负载均衡与高可用
-
Amoeba 实现 MySQL 高可用、负载均衡和读写分离
-
DVD数码相册大师.rar
-
龙芯生态应用开发基础:C语言精要
-
MaxScale 实现 MySQL 读写分离与负载均衡