python进程和线程

进程和线程的概念 - 什么是进程 / 什么是线程 /

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一个线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令。 一个程序的执行实例就是一个进程。每一个进程提供执行程序所需的所有资源。(进程本质上是资源的集合)

使用进程 - fork函数 / multiprocessing模块 / 进程池 / 进程间通信

fork()

import os
pid = os.fork()
if pid = 0:
    print('******' %os.getpid())
else:
    print(''***' %os.getpid())

如图,if语句和else语句中打印了,这就是fork()调用,返回两次,因为操作系统自动把当前程序(父进程)复制了一份(称为子进程)分别在父进程和子进程内放回。
我们用一个变量pid来接收返回值。
子进程的返回值永远是0,这就进入了if语句,为True,打印第一句话,而父进程的返回值就是子进程的ID编号,所以进入else语句,打印第二句话。

multiprocessing模块

管理进程模块

Process(用于创建进程模块)      Pool(用于创建管理进程池)

Queue(用于进程通信,资源共享)   Value,Array(用于进程通信,资源共享)

Pipe(用于管道通信)      Manager(用于资源共享)

同步子进程模块:

Condition    Event    Lock     RLock    Semaphore

Process模块用来创建子进程,是Multiprocessing核心模块,使用方式与Threading类似,可以实现多进程的创建,启动,关闭等操作。

一般需要传入target目标函数,args函数的参数

进程池

初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行,

from multiprocessing import Pool
import os,time,random
 
def worker(msg):
    t_start = time.time()
    print("%s开始执行,进程号为%d"%(msg,os.getpid()))
    #random.random()随机生成0~1之间的浮点数
    time.sleep(random.random()*2) 
    t_stop = time.time()
    print(msg,"执行完毕,耗时%0.2f"%(t_stop-t_start))
 
po=Pool(3) #定义一个进程池,最大进程数3
for i in range(0,10):
    #Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))
    #每次循环将会用空闲出来的子进程去调用目标
    po.apply_async(worker,(i,))
 
print("----start----")
po.close() #关闭进程池,关闭后po不再接收新的请求
po.join() #等待po中所有子进程执行完成,必须放在close语句之后
print("-----end-----")
————————————————
版权声明:本文为CSDN博主「一人在山旁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38260497/article/details/87900851

常用函数:

apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;

apply(func[, args[, kwds]]):使用阻塞方式调用func

close():关闭Pool,使其不再接受新的任务;

terminate():不管任务是否完成,立即终止;

join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;
 

进程间通信

Queue 

Put方法:以插入数据到队列中,他还有两个可选参数:blocked和timeout。详情自行百度

Get方法:从队列读取并且删除一个元素。同样,他还有两个可选参数:blocked和timeout。    

Pipe

Pipe常用于两个进程,两个进程分别位于管道的两端

Pipe方法返回(comm1,conn2)代表一个管道的两端,Pipe方法有duplex参数,默认True,即全双工模式,若为Flalse,conn1只负责接收信息,conn2负责发送。

使用线程 - thread模块 / threading模块 / Thread类 / Lock类 / Condition类 / 线程池

对象描述
Thread表示一个执行线程的对象
Lock锁对象
RLock可重入锁对象,使单一线程可以(再次)获得已持有的锁(递归锁)
Condition条件变量对象,使得一个线程等待另外一个线程满足特定的条件,比如改变状态或者某个数据值
Event 条件变量的通用版本,任意数量的线程等待某个事件的发生,在该事件发生后所有的线程都将被激活
Semaphore为线程间的有限资源提供一个计数器,如果没有可用资源时会被阻塞
BoundedSemaphore于Semaphore相似,不过它不允许超过初始值
Timer于Thread类似,不过它要在运行前等待一定时间
Barrier创建一个障碍,必须达到指定数量的线程后才可以继续

属性描述
Thread类属性
name线程名
ident线程的标识符
daemon布尔值,表示这个线程是否是守护线程
Thread类方法
__init__(group=None,target=None,name=None,args=(),kwargs={},verbose=None,daemon=None)实例化一个线程对象,需要一个可调用的target对象,以及参数args或者kwargs。还可以传递name和group参数。daemon的值将会设定thread.daemon的属性
start()开始执行该线程
run()定义线程的方法。(通常开发者应该在子类中重写)
join(timeout=None)直至启动的线程终止之前一直挂起;除非给出了timeout(单位秒),否则一直被阻塞
getName()返回线程名(该方法已被弃用)
setName()设定线程名(该方法已弃用)
isAlive布尔值,表示这个线程是否还存活(驼峰式命名,python2.6版本开始已被取代)
isDaemon()布尔值,表示是否是守护线程(已经弃用)
setDaemon(布尔值)在线程start()之前调用,把线程的守护标识设定为指定的布尔值(已弃用)

线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,即 ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。

如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值