第八篇 并发(进程和线程)

Python里执行并发有进程和线程两个,分布使用 threading 和multiprocessing 两个库,一般用的是这两个库里的Thread和Process

from threading import Thread   # 线程 : 同时运行

from multiprocessing import Process  # 进程

进程和线程的使用场景:

1. 一般在有大量的数据(耗时)操作的时候,会用到线程和进程

2.python里要优先用进程,因为Python里的线程有个自带的bug,全局解释器锁

示例1:有大猫和小猫睡觉的两个模拟耗时的操作,如果不用并发,执行效果就是从上到下顺序 串行执行的

from threading import Thread   # 线程 : 同时运行
import time, random

# 模拟耗时操作:大猫和小猫睡觉
def daMaoSleep(n):
    print("大猫开始睡觉了,它要睡{}秒".format(n) )
    time.sleep(n)
    print("现在大猫睡醒了")


def xiaoMaoSleep(n):
    print("小猫开始睡觉了,它要睡{}秒".format(n) )
    time.sleep(n)
    print("现在小猫睡醒了")

if __name__ == '__main__':
    # 不适用线程和进程,是顺序串行的
    n_da = random.randint(3,5)
    n_xiao = random.randint(3,6)
    # 使用线程库进行并行,注意target是函数名,args是参数,参数必须是元组
    # target=传参是要运行的函数,args=(n,) args是个元组,如果只有一个参数,要带逗号的
    # 使用线程库进行并行,注意target是函数名,args是参数,参数必须是元组
    # 执行大猫睡觉
    thread = Thread(target=daMaoSleep,args=(n_da,))
    thread.start()

    # 执行小猫睡觉
    thread = Thread(target=xiaoMaoSleep,args=(n_xiao,))
    thread.start()

# 输出
大猫开始睡觉了,它要睡4秒
小猫开始睡觉了,它要睡3秒
现在小猫睡醒了
现在大猫睡醒了

 

示例2:如果想让大猫和小猫同时开始睡觉,怎么操作呢?

这里用线程的方式实现并发演示

from multiprocessing import Process  # 进程
import time, random


# 模拟耗时操作:大猫和小猫睡觉
def daMaoSleep(n):
    print("大猫开始睡觉了,它要睡{}秒".format(n) )
    time.sleep(n)
    print("现在大猫睡醒了")


def xiaoMaoSleep(n):
    print("小猫开始睡觉了,它要睡{}秒".format(n) )
    time.sleep(n)
    print("现在小猫睡醒了")

if __name__ == '__main__':
    n_da = random.randint(3,5)
    n_xiao = random.randint(3,6)
    # 使用进程库进行并行,注意target是函数名,args是参数,参数必须是元组
    # target=传参是要运行的函数,args=(n,) args是个元组,如果只有一个参数,要带逗号的
    # 使用进程库进行并行,注意target是函数名,args是参数,参数必须是元组
    # 执行大猫睡觉
    process = Process(target=daMaoSleep,args=(n_da,))
    process.start()

    # 执行小猫睡觉
    process = Process(target=xiaoMaoSleep,args=(n_xiao,))
    process.start()


# 输出
大猫开始睡觉了,它要睡4秒
小猫开始睡觉了,它要睡3秒
现在小猫睡醒了
现在大猫睡醒了

注意避免踩坑:进程和线程一定要写在 if __name__ == '__main__' 里面的,否则会报错

进程与线程的区别:

什么是进程,什么是线程

系统要做一件事,运行一个任务,所有运行的任务通常就是一个程序;

每个运行中的程序就是一个进程,这一点在任务管理器上面可以形象的看到。

当一个程序运行时,内部可能会包含多个顺序执行流,每个顺序执行流就是一个线程。

 

关于进程的特性

独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间。在没有经过进程本身运行的情况下是不能访问其中的内容的。

动态性:进程与程序的区别在于,程序是静态的,进程是动态的。程序只是一个静态的指令集合,而进程是一个正在系统中运行的指令集合。有了时间的概念,如生命周期;

并发性:进程之间,交替着执行。

 

线程,一个顺序执行流;

它是进程的组成部分,一个进程可以有多个线程。

 

关于线程的特性,或是它的优势

1、进程之间不能共享内存,单线程之间共享内存非常的容易

2、系统创建进程需要为该进程重新分配系统资源,但创建线程的代价很小。因此多线程的实现多任务并发比多进程实现并发的效率高

3、java语言内置多线程功能支持,而不是单纯的作为底层操作系统的调度方式

 

总结:

一个程序运行至少一个进程,一个进程里面至少包含一个线程,线程是进程的组成部分。

线程相对于进程而言,很强大了,做到了资源的共享,资源的损耗降低,人为的手工控制程序的运行。

 

多进程通信的方式有哪些?
1. 共享内存
2. 信号
3. 信号量
4. 管道
5. socket通信

多线程的通信方式有哪些?
因为线程运作在进程里里面,所以多线程的通信方式也就是多线程的通信方式

 

不过,总的来说,目前进程和线程已经过时了,当前主流的处理方式都用消息队列实现

 

 

 

posted @ 2019-08-09 14:33  mamingchen  阅读(430)  评论(0编辑  收藏  举报