4.2 进程

目录

4.2.1 相关概念

  4.2.1.1 进程

  4.2.1.2 同步/异步

  4.2.1.3 阻塞/非阻塞

  4.2.1.4 并发/并行

  4.2.1.5 进程状态与调度

4.2.2 多进程

  4.2.1.1 创建进程

  4.2.1.2 相关属性

  4.2.1.1 相关方法

4.2.3 进程互斥锁

4.2.4 进程池

  4.2.4.1 创建进程池

  4.2.4.2 相关方法

  4.2.4.3 操作实例

4.2.1 相关概念

 4.2.1.1 进程

 4.2.1.2 同步/异步

 4.2.1.3 阻塞/非阻塞

 4.2.1.4 并发/并行

顺序执行:你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
       并发:你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
       并行:你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行

 4.2.1.5 进程状态与调度

(1)就绪(Ready)状态

当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。

(2)执行/运行(Running)状态当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。

(3)阻塞(Blocked)状态正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

4.2.2 多进程

4.2.1.1 创建进程

  示例

from multiprocessing import Process
import time

def task(name):
    print(‘{} is running!‘.format(name))
    time.sleep(3)
    print(‘{} is done!‘.format(name))

# Windows开子进程要写在__name__==__main__下
# 因为开子进程会重新加载父进程的内容
if __name__ == ‘__main__‘:
    # 创建一个Python中的进程对象
    p = Process(target=task, args=(‘t1‘, ))
    # p = Process(target=task, kwargs={‘name‘: ‘t1‘})
    p.start()  # 调用操作系统接口启动一个进程执行命令
    print(‘--- 主进程 ----‘)

  多进程示例

from multiprocessing import Process
import time

def task(name):
    print(‘{} is running!‘.format(name))
    time.sleep(3)
    print(‘{} is done!‘.format(name))

if __name__ == ‘__main__‘:
    for i in range(10):
        p = Process(target=task, args=(i, ))
        p.start()
    print(‘--- 主进程 ----‘)

  继承方式创建多进程

import os
from multiprocessing import Process

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print(os.getpid())
        print(‘%s 正在和女主播聊天‘ %self.name)

p1=MyProcess(‘wupeiqi‘)
p2=MyProcess(‘yuanhao‘)
p3=MyProcess(‘nezha‘)

p1.start() #start会自动调用run
p2.start()
# p2.run()
p3.start()

p1.join()
p2.join()
p3.join()

print(‘主线程‘)

4.2.1.2 相关属性

p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
p.name:进程的名称
p.pid:进程的pid
p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
p.authkey:进程的身份验证键,

  daemon 守护进程示例

from multiprocessing import Process
import time
def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")

if __name__ == ‘__main__‘:
    p1=Process(target=foo)
    p2=Process(target=bar)

    p1.daemon=True
    p1.start()
    p2.start()
    time.sleep(0.1)
    print("main-------")

"""
# 主进程结束了,守护进程随着结束,导致p1 的 end123 无法打印出来
123
456
main-------
end456
"""

4.2.1.3 相关方法

p.start():启动进程,并调用该子进程中的p.run()
p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
p.is_alive():如果p仍然运行,返回True
p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程 

   join 的示例

from multiprocessing import Process
import time

def task(n):
    print(‘这是子进程:{}‘.format(n))
    time.sleep(n)
    print(‘子进程:{}结束了!‘.format(n))

if __name__ == ‘__main__‘:
    start_time = time.time()
    p1 = Process(target=task, args=(1,))
    p2 = Process(target=task, args=(2,))
    p3 = Process(target=task, args=(3,))
    p1.start()
    p2.start()
    p3.start()

    p1.join()
    p2.join()
    p3.join()
    print(‘我是主进程‘)
    print(‘共耗时:{}‘.format(time.time()-start_time))

"""
# 未加 join 主进程不等待其他子进程程序结束便自己先行结束
我是主进程
共耗时:0.021976947784423828
这是子进程:1
这是子进程:2
这是子进程:3
子进程:1结束了!
子进程:2结束了!
子进程:3结束了!
"""

"""
# 加 join 主进程等待其他子进程程序结束后再结束
这是子进程:1
这是子进程:2
这是子进程:3
子进程:1结束了!
子进程:2结束了!
子进程:3结束了!
我是主进程
共耗时:3.130025625228882
"""

4.2.3 进程互斥锁

  洗手间模型演示无锁导致的问题

from multiprocessing import Process
import time
import random

def task1():
    print(‘这是 task1 任务‘.center(30, ‘-‘))
    print(‘task1 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task1 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task1 走出了洗手间‘)

def task2():
    print(‘这是 task2 任务‘.center(30, ‘-‘))
    print(‘task2 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task2 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task2 走出了洗手间‘)

def task3():
    print(‘这是 task3 任务‘.center(30, ‘-‘))
    print(‘task3 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task3 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task3 走出了洗手间‘)

if __name__ == ‘__main__‘:
    p1 = Process(target=task1)
    p2 = Process(target=task2)
    p3 = Process(target=task3)

    p1.start()
    p2.start()
    p3.start()

"""
# 洗手间只能进一个人,尼玛你们.....
---------这是 task1 任务----------
task1 进了洗手间
---------这是 task2 任务----------
task2 进了洗手间
---------这是 task3 任务----------
task3 进了洗手间
task2 办事呢...
task1 办事呢...
task3 办事呢...
task1 走出了洗手间
task2 走出了洗手间
task3 走出了洗手间
"""

  加锁解决示例

from multiprocessing import Process, Lock
import time
import random

# 生成一个互斥锁
mutex_lock = Lock()

def task1(lock):
    # 锁门
    lock.acquire()
    print(‘这是 task1 任务‘.center(30, ‘-‘))
    print(‘task1 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task1 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task1 走出了洗手间‘)
    # 释放锁
    lock.release()

def task2(lock):
    # 锁门
    lock.acquire()
    print(‘这是 task2 任务‘.center(30, ‘-‘))
    print(‘task2 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task2 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task2 走出了洗手间‘)
    # 释放锁
    lock.release()

def task3(lock):
    # 锁门
    lock.acquire()
    print(‘这是 task3 任务‘.center(30, ‘-‘))
    print(‘task3 进了洗手间‘)
    time.sleep(random.randint(1, 3))
    print(‘task3 办事呢...‘)
    time.sleep(random.randint(1, 3))
    print(‘task3 走出了洗手间‘)
    # 释放锁
    lock.release()

if __name__ == ‘__main__‘:
    p1 = Process(target=task1, args=(mutex_lock, ))
    p2 = Process(target=task2, args=(mutex_lock, ))
    p3 = Process(target=task3, args=(mutex_lock, ))

    # 释放新建进程的信号,具体谁先启动无法确定
    p1.start()
    p2.start()
    p3.start()

"""
---------这是 task2 任务----------
task2 进了洗手间
task2 办事呢...
task2 走出了洗手间
---------这是 task1 任务----------
task1 进了洗手间
task1 办事呢...
task1 走出了洗手间
---------这是 task3 任务----------
task3 进了洗手间
task3 办事呢...
task3 走出了洗手间
"""

  加锁的弊端

  

4.2.4 进程池

4.2.4.1 创建进程池

4.2.4.2 相关方法

p.apply(func [, args [, kwargs]])  在一个池工作进程中执行func(*args,**kwargs),然后返回结果。
  需要强调的是:此操作并不会在所有池工作进程中并执行func函数。
    如果要通过不同参数并发地执行func函数,必须从不同线程调用p.apply()函数或者使用p.apply_async()

p.apply_async(func [, args [, kwargs[callback,]]])  在一个池工作进程中执行func(*args,**kwargs),然后返回结果  callback是可调用对象,接收输入参数。当func的结果变为可用时, 将传递给callback
  callback禁止执行任何阻塞操作,否则将接收其他异步操作中的结果。

p.close()
  关闭进程池,防止进一步操作
  禁止往进程池内在添加任务(需要注意的是一定要写在close()的上方)

p.join()
  等待所有工作进程退出。
  此方法只能在close()或teminate()之后调用

4.2.4.3 相关实例

  穿行进程池实例

from multiprocessing import Pool
import os,time
def task(n):
    print(‘[%s] is running‘%os.getpid())
    time.sleep(2)
    print(‘[%s] is done‘%os.getpid())
    return n**2
if __name__ == ‘__main__‘:
    # print(os.cpu_count())  #查看cpu个数
    p = Pool(4) #最大四个进程
    for i in range(1,7):#开7个任务
        res = p.apply(task,args=(i,))  #同步的,等着一个运行完才执行另一个
        print(‘本次任务的结束:%s‘%res)
    p.close()#禁止往进程池内在添加任务
    p.join() #在等进程池
    print(‘主‘)

apply同步进程池(阻塞)(串行)

   并行进程池实例

from multiprocessing import Pool
import os,time
def walk(n):
    print(‘task[%s] running...‘%os.getpid())
    time.sleep(3)
    return n**2
if __name__ == ‘__main__‘:
     p = Pool(4)
     res_obj_l = []
     for i in range(10):
         res = p.apply_async(walk,args=(i,))
         # print(res)  #打印出来的是对象
         res_obj_l.append(res)  #那么现在拿到的是一个列表,怎么得到值呢?我们用个.get方法
     p.close() #禁止往进程池里添加任务
     p.join()
     # print(res_obj_l)
     print([obj.get() for obj in res_obj_l])  #这样就得到了

  回调函数什么时候用?(回调函数在爬虫中最常用)

    造数据的非常耗时

    处理数据的时候不耗时

  带有回调函数的实例

from  multiprocessing import Pool
import requests
import os
import time
def get_page(url):
    print(‘<%s> is getting [%s]‘ %(os.getpid(),url))
    response = requests.get(url)  #得到地址
    time.sleep(2)
    print(‘<%s> is  done [%s]‘%(os.getpid(),url))
    return {‘url‘:url,‘text‘:response.text}
def parse_page(res):
    ‘‘‘解析函数‘‘‘
    print(‘<%s> parse [%s]‘%(os.getpid(),res[‘url‘]))
    with open(‘db.txt‘,‘a‘) as f:
        parse_res = ‘url:%s size:%s\n‘ %(res[‘url‘],len(res[‘text‘]))
        f.write(parse_res)
if __name__ == ‘__main__‘:
    p = Pool(4)
    urls = [
        ‘https://www.baidu.com‘,
        ‘http://www.openstack.org‘,
        ‘https://www.python.org‘,
        ‘https://help.github.com/‘,
        ‘http://www.sina.com.cn/‘
    ]
    for url in urls:
        obj = p.apply_async(get_page,args=(url,),callback=parse_page)
    p.close()
    p.join()
    print(‘主‘,os.getpid())  #都不用.get()方法了

回调函数(下载网页的小例子)

  无需回调函数的实例

from  multiprocessing import Pool
import requests
import os
def get_page(url):
    print(‘<%os> get [%s]‘ %(os.getpid(),url))
    response = requests.get(url)  #得到地址  response响应
    return {‘url‘:url,‘text‘:response.text}
if __name__ == ‘__main__‘:
    p = Pool(4)
    urls = [
        ‘https://www.baidu.com‘,
        ‘http://www.openstack.org‘,
        ‘https://www.python.org‘,
        ‘https://help.github.com/‘,
        ‘http://www.sina.com.cn/‘
    ]
    obj_l= []
    for url in urls:
        obj = p.apply_async(get_page,args=(url,))
        obj_l.append(obj)
    p.close()
    p.join()
    print([obj.get() for obj in obj_l])

下载网页小例子(无需回调函数)

原文地址:https://www.cnblogs.com/shijieli/p/10340239.html

时间: 2024-10-20 18:11:09

4.2 进程的相关文章

C#:多进程开发,控制进程数量

正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下: System.Threading.Tasks.Task task=System.Threading.Tasks.Task.Factory.StartNew( (object mystate) => { Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString()); process.WaitF

C# 远程服务器 安装、卸载 Windows 服务,读取远程注册表,关闭杀掉远程进程

这里安装windows服务我们用sc命令,这里需要远程服务器IP,服务名称.显示名称.描述以及执行文件,安装后需要验证服务是否安装成功,验证方法可以直接调用ServiceController来查询服务,也可以通过远程注册表来查找服务的执行文件:那么卸载文件我们也就用SC命令了,卸载后需要检测是否卸载成功,修改显示名称和描述也用sc命令.至于停止和启动Windows服务我们可以用sc命令也可以用ServiceController的API,当停止失败的时候我们会强制杀掉远程进程,在卸载windows

【转】linux下杀死进程(kill)的N种方法

转载一篇,最原始的出处已不可考,望见谅! 常规篇: 首先,用ps查看进程,方法如下: $ ps -ef --smx       1822     1  0 11:38 ?        00:00:49 gnome-terminalsmx       1823  1822  0 11:38 ?        00:00:00 gnome-pty-helpersmx       1824  1822  0 11:38 pts/0    00:00:02 bashsmx       1827    

os -- 进程的控制

os -- 进程的控制 新建 模板 小书匠 参考 <计算机操作系统>(第四版) 汤小丹等编著 概念引入 进程控制 进程控制是最基本的功能,负责创建进程.结束进程等功能,一般由 OS 内核中的原语来实现 原语 所谓原语,就是由若干条指令组成的,用于完成一定功能的一个过程,算是不可分割的.最基本的操作 Note 接下来原语基本用于所有的操作 操作系统内核 操作系统将一些常用或者运行频率较高的模块(如时钟管理.进程调度等)常驻内存,这些就被称为 OS 内核 两大功能 支撑功能 中断处理 时钟管理 原

linux进程管理

进程管理 进程 Process 某应用程序打开的进程 PID Process ID 类型: 用户空间进程 内核空间进程 静态查看进程的状态 # ps [[email protected] ~]# ps >>>>查看本终端的进程 PID TTY          TIME CMD 4206 pts/0    00:00:00 bash 4378 pts/0    00:00:00 ps 选项的使用方式: BSD风格:选项没有横线- ps aux SysV风格:选项需要带有横线-  

linux基本命令整理(三):进程和vim

linux基本命令整理(三) -----------进程和vim 一.进程 1.查看进程 ps:将某个时间点的程序运行的状况截取下来 a:所有的进程 x:后台进程 u:有效的使用者相关的进程(常用组合aux) -IA:也能观察系统所有的数据 axjf:连同部分的程序树状态 -I:今查看和自己bash相关的程序 top:动态的观察进程的变化 -d:后面接描述,就是整个页面刷新的时间:默认是5秒 -b:以批次的方式执行top -n:与-b搭配使用,意义是需要进行几次top的输出结果 如:top -b

内存池、进程池、线程池

首先介绍一个概念"池化技术 ".池化技术 一言以蔽之就是:提前保存大量的资源,以备不时之需以及重复使用. 池化技术应用广泛,如内存池,线程池,连接池等等.内存池相关的内容,建议看看Apache.Nginx等开源web服务器的内存池实现. 起因:由于在实际应用当中,分配内存.创建进程.线程都会设计到一些系统调用,系统调用需要导致程序从用户态切换到内核态,是非常耗时的操作.           因此,当程序中需要频繁的进行内存申请释放,进程.线程创建销毁等操作时,通常会使用内存池.进程池.

Linux进程的睡眠和唤醒

1   Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING.一旦一个运行中的进程时间片用完, Linux内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行. 当然,一个进程也可以主动释放CPU的控制权.函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU.一旦这个主动放弃CPU的进程被重新调度占用CPU,那么它将从

C#杀掉进程的方法

1 private static string CmdName = "cmd"; 2 /// <summary> 3 /// 关闭进程 4 /// </summary> 5 /// <param name="processName">进程名</param> 6 private void KillProcess(string processName) 7 { 8 Process[] myproc = Process.Ge

Linux进程管理与调度-之-目录导航【转】

转自:http://blog.csdn.net/gatieme/article/details/51456569 版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatieme 目录(?)[-] 项目链接 进程的描述 进程的创建 进程的加载与运行 进程的退出 进程的调度 调度普通进程-完全公平调度器CFS 日期 内核版本 架构 作者 GitHub CSDN 2016-07-21 Linux-4.6 X86 & arm gatieme