Python多线程编程入门详解

目录
  • 一、任务、进程和线程
    • 任务
    • 进程
    • 线程
    • 进程和线程的关系
  • 二、Python既支持多进程,又支持多线程
    • Python实现多进程
    • Process进程类的说明
    • Python实现多线程
      • 线程类Thread
  • 总结

一、任务、进程和线程

现代操作系统比如Mac OS XLinuxWindows等,都是支持“多任务”的操作系统。

什么叫“多任务”(multitasking)呢?简单地说,就是操作系统可以同时运行多个任务。例如你一边在用浏览器上查资料,一边在听MP3,一边在用Word写文档,这就是多任务。

打开Windows的任务管理器,可以直观的了解一下:

任务

(task)是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是一个线程。简而言之,它指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以作为一个进程来实现,也可以作为一个线程(或作为一个中断任务)来实现。

单核CPU如何实现“多任务”

三个任务A,B,C在单个CPU上交替执行,逻辑上表现为三个执行实例并发执行,但实质物理上是串行执行。

多核CPU如何实现“多任务”

多任务的真正并行只能在多核CPU上实现,但是,一般而言,任务的数量多于CPU的核数,还是需要将多个任务轮流调度到每个核上执行。

单核与多核处理器(Multi-core processor)示例

多核CPU:简单地说是将多个核心装载一个封装里,外观上看是一个处理器。

串行:一个处理完再一个。

并行:指两个或者多个事件在同一时刻发生。

并发:指两个或多个事件在同一时间间隔内发生。

例如:并发时你正在吃饭,吃到一半电话响,去接电话,接完后继续吃饭;并行时边吃饭边打电话。

进程

(process)常常被定义为程序的执行。可以把一个进程看成是一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于它自己。

线程

(tread)则是某一进程中一路单独运行的程序。也就是说,线程存在于进程之中。一个进程由一个或多个线程构成,各线程共享相同的代码和全局数据 ,但各有其自己的堆栈。由于堆栈是每个线程一个,所以局部变量对每一线程来说是私有的 。由于所有线程共享同样的代码和全局数据,它们比进程更紧密,比单独的进程间更趋向于相互作用,线程间的相互作用更容易些,因为它们本身就有某些供通信用的共享内存:进程的全局数据。

进程和线程的关系

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

二、Python既支持多进程,又支持多线程

multiprocessing --- 基于进程的并行 — Python 3.10.0 文档

threading --- 基于线程的并行 — Python 3.10.0 文档

Python实现多进程

在Unix/Linux下,Mac系统是基于BSD(Unix的一种)内核,都可以使用fork()调用实现多进程,Python的os模块封装了常见的系统调用,其中就包括fork。例如:

import os

print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()  #Windows中不支持fork(),将报错
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
 

需要注意的是,上述代码在Unix/Linux、Mac系统中可以运行,但在Windows中运行报错:

AttributeError: module 'os' has no attribute 'fork'

因为Windows没有fork调用,怎么办?

multiprocessing模块是跨平台版本的多进程模块。在Windows上用Python编写多进程的程序,可以使用multiprocessing模块。multiprocessing模块提供了一个Process类来代表一个进程对象。

Process进程类的说明

Process([group [, target [, name [, args [, kwargs]]]]])

  • group:指定进程组,目前只能使用None
  • target:执行的目标任务名
  • name:进程名字,默认为Process-N,N为从1开始递增的整数
  • args:以元组方式给执行任务传参
  • kwargs:以字典方式给执行任务传参

Process创建的实例对象的常用方法:

  • start():启动子进程实例(创建子进程)
  • join():等待子进程执行结束
  • terminate():不管任务是否完成,立即终止子进程

Process创建的实例对象的常用属性:

例如:

import multiprocessing
import time

# 跳舞任务
def dance():
    for i in range(3):
        print("跳舞中...")
        time.sleep(0.2)

# 唱歌任务
def sing():
    for i in range(3):
        print("唱歌中...")
        time.sleep(0.2)

dance_process = multiprocessing.Process(target=dance(), name="myprocess1")
sing_process = multiprocessing.Process(target=sing())

# 启动子进程执行对应的任务
dance_process.start()
sing_process.start()

执行结果如下图:

Python实现多线程

多任务可以由多进程完成,也可以由一个进程内的多线程完成。

Python的标准库提供了两个模块:_threadthreading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,使用threading这个高级模块。

线程类Thread

Thread([group [, target [, name [, args [, kwargs]]]]])

  • group: 线程组,目前只能使用None
  • target: 执行的目标任务名
  • args: 以元组的方式给执行任务传参
  • kwargs: 以字典方式给执行任务传参
  • name: 线程名,一般不用设置

Thread类提供了以下方法:

  • run(): 用以表示线程活动的方法。
  • start():启动线程活动。
  • join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
  • isAlive(): 返回线程是否活动的。
  • getName(): 返回线程名。
  • setName(): 设置线程名。

启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行,例子:

import time, threading

# 新线程执行的代码:
def loop():
    print('thread %s is running...' % threading.current_thread().name)
    n = 0
    while n < 5:
        n = n + 1
        print('thread %s >>> %s' % (threading.current_thread().name, n))
        time.sleep(1)
    print('thread %s ended.' % threading.current_thread().name)

print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
 

执行结果如下图:

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • python中threading和queue库实现多线程编程

    摘要 本文主要介绍了利用python的 threading和queue库实现多线程编程,并封装为一个类,方便读者嵌入自己的业务逻辑.最后以机器学习的一个超参数选择为例进行演示. 多线程实现逻辑封装 实例化该类后,在.object_func函数中加入自己的业务逻辑,再调用.run方法即可. # -*- coding: utf-8 -*- # @Time : 2021/2/4 14:36 # @Author : CyrusMay WJ # @FileName: run.py # @Software:

  • python多线程抽象编程模型详解

    最近需要完成一个多线程下载的工具,对其中的多线程下载进行了一个抽象,可以对所有需要使用到多线程编程的地方统一使用这个模型来进行编写. 主要结构: 1.基于Queue标准库实现了一个类似线程池的工具,用户指定提交任务线程submitter与工作线程worker数目,所有线程分别设置为后台运行,提供等待线程运行完成的接口. 2.所有需要完成的任务抽象成task,提供单独的无参数调用方式,供worker线程调用:task以生成器的方式作为参数提供,供submitter调用. 3.所有需要进行线程交互的

  • 详解Python并发编程之创建多线程的几种方法

    大家好,并发编程 今天开始进入第二篇. 今天的内容会比较基础,主要是为了让新手也能无障碍地阅读,所以还是要再巩固下基础.学完了基础,你们也就能很顺畅地跟着我的思路理解以后的文章. 本文目录 学会使用函数创建多线程 学会使用类创建多线程 多线程:必学函数讲解 经过总结,Python创建多线程主要有如下两种方法: 函数 类 接下来,我们就来揭开多线程的神秘面纱. . 学会使用函数创建多线程 在Python3中,Python提供了一个内置模块 threading.Thread,可以很方便地让我们创建多

  • 深入理解python多线程编程

    进程 进程的概念: 进程是资源分配的最小单位,他是操作系统进行资源分配和调度运行的基本单位.通俗理解:一个正在运行的一个程序就是一个进程.例如:正在运行的qq.wechat等,它们都是一个进程. 进程的创建步骤 1.导入进程包  import multiprocessing 2.通过进程类创建进程对象  进程对象 = multiprocessing.Process() 3.启动进程执行任务  进程对象.start() import multiprocessing import time def

  • Python多线程编程之多线程加锁操作示例

    本文实例讲述了Python多线程编程之多线程加锁操作.分享给大家供大家参考,具体如下: Python语言本身是支持多线程的,不像PHP语言. 下面的例子是多个线程做同一批任务,任务总是有task_num个,每次线程做一个任务(print),做完后继续取任务,直到所有任务完成为止. # -*- coding:utf-8 -*- #! python2 import threading start_task = 0 task_num = 10000 mu = threading.Lock() ###通

  • Python并发编程队列与多线程最快发送http请求方式

    目录 队列+多线程 线程池 协程 + aiohttp grequests 最后的话 Python 并发编程有很多方法,多线程的标准库 threading,concurrency,协程 asyncio,当然还有 grequests 这种异步库,每一个都可以实现上述需求,下面一一用代码实现一下,本文的代码可以直接运行,给你以后的并发编程作为参考: 队列+多线程 定义一个大小为 400 的队列,然后开启 200 个线程,每个线程都是不断的从队列中获取 url 并访问. 主线程读取文件中的 url 放入

  • Python多线程编程之threading模块详解

    一.介绍 线程是什么?线程有啥用?线程和进程的区别是什么? 线程是操作系统能够进行运算调度的最小单位.被包含在进程中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 二.Python如何创建线程 2.1 方法一: 创建Thread对象 步骤: 1.目标函数 2.实例化Thread对象 3.调用start()方法 import threading # 目标函数1 def fun1(num): for i in range(

  • python网络编程之多线程同时接受和发送

    本文实例为大家分享了python多线程同时接受和发的具体代码,供大家参考,具体内容如下 ''' 模仿qq 同时可以发送信息和接受信息多线程 ''' from socket import * from time import sleep import threading # 负责接收数据 def recvData(): udpRecvSocket = socket(AF_INET,SOCK_DGRAM) # 默认使用8080端口 myRecvPort = 8080 bindAddr = ('',8

  • Python多线程编程入门详解

    目录 一.任务.进程和线程 任务 进程 线程 进程和线程的关系 二.Python既支持多进程,又支持多线程 Python实现多进程 Process进程类的说明 Python实现多线程 线程类Thread 总结 一.任务.进程和线程 现代操作系统比如Mac OS X, Linux,Windows等,都是支持"多任务"的操作系统. 什么叫"多任务"(multitasking)呢?简单地说,就是操作系统可以同时运行多个任务.例如你一边在用浏览器上查资料,一边在听MP3,一

  • python多线程超详细详解

    python中的多线程是一个非常重要的知识点,今天为大家对多线程进行详细的说明,代码中的注释有多线程的知识点还有测试用的实例. import threading from threading import Lock,Thread import time,os ''' python多线程详解 什么是线程? 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位. 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程

  • linux下的C\C++多进程多线程编程实例详解

    linux下的C\C++多进程多线程编程实例详解 1.多进程编程 #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t child_pid; /* 创建一个子进程 */ child_pid = fork(); if(child_pid == 0) { printf("child pid\n"); exit(0); } else { print

  • Python 多线程的实例详解

     Python 多线程的实例详解 一)线程基础 1.创建线程: thread模块提供了start_new_thread函数,用以创建线程.start_new_thread函数成功创建后还可以对其进行操作. 其函数原型: start_new_thread(function,atgs[,kwargs]) 其参数含义如下: function: 在线程中执行的函数名     args:元组形式的参数列表.     kwargs: 可选参数,以字典的形式指定参数 方法一:通过使用thread模块中的函数创

  • java多线程编程技术详解和实例代码

     java多线程编程技术详解和实例代码 1.   Java和他的API都可以使用并发. 可以指定程序包含不同的执行线程,每个线程都具有自己的方法调用堆栈和程序计数器,使得线程在与其他线程并发地执行能够共享程序范围内的资源,比如共享内存,这种能力被称为多线程编程(multithreading),在核心的C和C++语言中并不具备这种能力,尽管他们影响了JAVA的设计. 2.   线程的生命周期 新线程的生命周期从"新生"状态开始.程序启动线程前,线程一直是"新生"状态:

  • python库h5py入门详解

    目录 h5py简单介绍 1.创建一个h5py文件 2.创建dataset数据集 3.创建group组 本文只是简单的对h5py库的基本创建文件,数据集和读取数据的方式进行介绍,作者刚接触h5py,完全靠看文档自学,如果哪里说的不对,欢迎纠正!如果读者需要进一步详细的学习h5py的更多知识,请参考h5py的官方文档. h5py简单介绍 h5py文件是存放两类对象的容器,数据集(dataset)和组(group),dataset类似数组类的数据集合,和numpy的数组差不多.group是像文件夹一样

  • Python socket编程实例详解

    本文实例形式较为详细的讲述了Python socket编程.分享给大家供大家参考.具体如下: 复制代码 代码如下: sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 上面的代码创建了一个socket对象.type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字).AF_INET表示创建的是ip v4的类型. 复制代码 代码如下: socket(address_family,type,proto

  • Python函数式编程实例详解

    本文实例讲述了Python函数式编程.分享给大家供大家参考,具体如下: 函数式编程就是一种抽象程度很高的编程范式,从计算机硬件->汇编语言->C语言->Python抽象程度越高.越贴近于计算,但执行效率也越低.纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用.而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的.函数式编程的一个特点就是,允许把函数

  • python多线程用法实例详解

    本文实例分析了python多线程用法.分享给大家供大家参考.具体如下: 今天在学习尝试学习python多线程的时候,突然发现自己一直对super的用法不是很清楚,所以先总结一些遇到的问题.当我尝试编写下面的代码的时候: 复制代码 代码如下: class A():     def __init__( self ):         print "A" class B( A ):     def __init__( self ):         super( B, self ).__in

  • JAVA多线程编程实例详解

    本文实例讲述了JAVA多线程编程.分享给大家供大家参考,具体如下: 进程是系统进行资源调度和分配的一个独立单位. 进程的特点 独立性:进程是系统中独立存在的实体,拥有自己的独立资源和私有空间.在没有经过进程本身允许的情况下,不能直接访问其他进程. 动态性:进程与程序的区别在于,前者是一个正在系统中活动的指令,而后者仅仅是一个静态的指令集合 并发性:多个进程可以在单个处理器上并发执行,而不受影响. 并发性和并行性的区别: 并行性:在同一时刻,有多条指令在多个处理器上同时执行(多个CPU) 并发性:

随机推荐