当前标签 / Thread / 总共5篇

Python 多线程和多进程爬虫

前面的 《Python 的网络请求 Requests 模块使用》 我们已经对爬虫的基本过程有了了解,而且整个过程比较顺畅,容易理解,但是很多情况下我们的爬取工作并不是如此轻松的,我们可能会面临一些特殊情况,例如今天要说的速度问题,如果有大量的页面需要爬取,我们还使用单一线程就很慢了。

多线程爬虫

我们先不考虑特别大型的爬取,本文所有的思路都是基于满足个人需求的中型爬取需要。我们可以使用多线程来并行爬取,这样就可以成倍的提高爬取速度。

我们先来感受一下如何使用多线程:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import _thread
import time

def print_time(threadName, delay):
    count = 0
    while count < 3:
        time.sleep(delay)
        count += 1
        print(threadName, time.ctime())

_thread.start_new_thread(print_time, ("Thread-1", 1))
_thread.start_new_thread(print_time, ("Thread-2", 2))

阅读更多

HandlerThread详解

概述

在日常开发中,我们经常会通过 new Thread(){}.start(); 的方式来开辟一个新的线程。但是如果我们想要多次执行任务的时候,通过这种方式我就会创建多个线程,这样会使我们的程序运行起来越来越慢。通常情况下我会采用 HandlerThread 的方式来开辟一个线程,那么 HandlerThread 是什么呢?今天我们来介绍一下 HandlerThread。

正文

HandlerThread 是 Thread 的一个子类,HandlerThread 自带 Looper 使他可以通过消息队列来重复使用当前线程,节省系统资源开销。这是它的优点也是缺点,每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。它的使用也比较简单。

HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();

mHandler = new Handler(thread.getLooper());
mHandler.post(new Runnable(){
    //...
});

接下来我们写一个完整的 Demo,然后在分析一下它的实现原理。

阅读更多

物联网开发中常见的几个标准协议

Let’s say you’re in the planning phase of an IoT project. You have a lot of decisions to make, and maybe you’re not sure where to start. In this article, we focus on a framework for how you can think about this problem of standards, protocols, and radios.

假设你正准备开始一个物联网项目,在开始项目之前你需要做很多选择,有可能你完全不知道从哪开始,这篇文章我们一起来看看如何选择标准的无线通信协议框架。

The framework, of course, depends on if your deployment is going to be internal, such as in a factory, or external, such as a consumer product. In this conversation, we’ll focus on products that are launching externally to a wider audience of customers, and for that, we have a lot to consider.

当然,这些无线通信协议框架是部署在你的设备内部进行通信的,物联网项目中还要考虑到一些外部的硬件,这些硬件都是在制作工厂完成的,所以本文讲重点关注一些使用比较广泛的通信产品。

阅读更多

Android内部分享[5]——后台线程和多线程的使用

概述

我们前面提到过,在 Android 中有一个核心线程 UI 线程(或者叫主线程),负责处理 UI 渲染(包括去测量和绘制图形),协调用户交互和生命周期事件等。如果这个主线程中发送了太多的耗时操作和工作就会影响用户体验,我们的应用就会变得缓慢或者无响应,甚至出现 ANR(Application Not Responding),所以对我们开发者而言应该将那些比较耗时或者大段很多的操作委托给其他线程来处理,这些线程(非 UI 线程)在后台帮我们处理完成后再交给我们主线程来重新渲染界面。或者有时候我们需要做一些非用户交互的任务,比如定时去和服务器同步一些数据,像这种后台任务也应该直接交给非主线程,让它们在后台帮我们完成。

需要我们特别注意的是,我们在使用多线程来处理任务的时候要考虑到后台任务可能会消耗过多的资源,例如RAM 和电量,在 Android 系统中为了最大的优化系统性能和电池电量,当用户看不到应用在前台的时候会限制后台线程的工作,有可能会杀死这些线程。

Android 6.0 (API 23) 中引入了一个叫 Doze 的模式和应用程序待机处理, 当我们的屏幕关闭(也就是我们通常说的锁屏)且设备静止的时候, Doze 模式会限制应用程序的一些行为,例如网络不可访问, 线程执行的任务停止等。在 Android 7.0 和 8.0 之后更是进一步限制了后台行为,例如在后台获取位置将被禁止,通过 wakelocks 唤醒应用也被禁止。在 Android 9.0 之后引入了 App Standby Buckets, 应用程序对资源的请求根据应用程序使用模式进行动态优先级排序

阅读更多

Java中的多线程

进程和线程

操作系统有两个容易混淆的概念,进程和线程

进程:一个计算机程序的运行实例,包含了需要执行的指令;有自己的独立地址空间,包含程序内容和数据;不同进程的地址空间是互相隔离的;进程拥有各种资源和状态信息,包括打开的文件、子进程和信号处理。 线程:表示程序的执行流程,是CPU调度执行的基本单位;线程有自己的程序计数器、寄存器、堆栈和帧。同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源。

进程是操作系统资源分配的最小单位(CPU时间, 内存空间),线程就是共享虚拟内存映射的进程,多个线程属于一个进程。

Java标准库提供了进程和线程相关的API,进程主要包括表示进程的java.lang.Process类和创建进程的java.lang.ProcessBuilder类

表示线程的是java.lang.Thread类,在虚拟机启动之后,通常只有Java类的main方法这个普通线程运行,运行时可以创建和启动新的线程;还有一类守护线程(damon thread),守护线程在后台运行,提供程序运行时所需的服务。当虚拟机中运行的所有线程都是守护线程时,虚拟机终止运行。

阅读更多