Python 基础之 线程与进程

    在前面已经接触过了,socket编程的基础知识,也通过socketserver 模块实现了并发,也就是多个客户端可以给服务器端发送消息,那接下来还有个问题,如何用多线程与多进程来实现并发呢?今天就来了解一下这方面的知识。

一、进程与线程的概念介绍

   多任务处理是指用户可以在同一时间内运行多个应用程序,每个应用程序被称作一个任务。Linux、windows就是支持多任务的操作系统,比起单任务系统它的功能增强了许多。

运行一个任务就需要cpu去处理,那同时运行多个任务就必须需要多个cpu?那如果有100个任务需要同时运行,就得买一个100核的cpu吗?显然不能! 现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢?

答案就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。

小结:一个cpu同一时刻只能运行一个“任务”;真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。

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

有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)

由于每个进程至少要干一件事,所以,一个进程至少有一个线程。当然,像Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂地交替运行,看起来就像同时执行一样。当然,真正地同时执行多线程需要多核CPU才可能实现。

小结:

  • 进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据集、进程控制块三部分组成。
  • 线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能。线程没有自己的系统资源。

二、进程和线程的关系

        进程是计算机中的程序关于某数据集上的一次运行活动(是代码执行的过程),是系统进行资源分配和调度的基本单位,是操作系统结构的基础。或者说进程是具有一定独立功能的程序关于某个数据集上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。(进程是一个资源单位)
        线程则是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。(线程就是一个 执行单位)

        我们用图片来形象的观察一下他们之间的关系:

Python 基础之 线程与进程

小结:

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

  • 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
  • CPU分给线程,即真正在CPU上运行的是线程。

三、并行和并发

    并行(Parallel Processing)是指一个系统具有处理多个任务(动作)的能力,(1个CPU进行切换就可以完成的)

    并发(concurrency Processing)指一个系统具有同时(唯一的时刻)处理多个任务(动作的)能力,(多核,eg:4核,4个CPU可同时处理1~4个任务的能力)。

   并发是并行的子集。(并发是并行的子集。比如在单核CPU系统上,只可能存在并发而不可能存在并行。)

 

四、同步和异步

    同步:当进程执行到一个IO(阻塞的时候),出现等待,这个就是同步。

    异步:当进程执行到一个IO(阻塞的时候),不会等待,直到数据到来之后再回过头来处理,这就是异步。

五、多线程(threading.Thread)

    线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。

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

   1. 创建线程的方式:

    1.直接创建:

import threading
import time

########直接创建线程的方式##############
def music(num): # 子线程的任务
    print('您现在听到的音乐数目为:%s'%(num),time.ctime())
    time.sleep(5)

if __name__ == '__main__':
    t1 = threading.Thread(target=music,args=(100,)) #定义一个线程实例对象(此时没有任何现象产生)
    t1.start() # 启动的这一时刻才产生出了子线程(创建的那句任然是主线程的)

    print('你输入的密码有误,请重新输入',time.ctime()) # 主线程的代码
直接创建

相关文章: