Day40:进程和并发

1.什么是进程
  • 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础;
  • 在早期面向进程设计的计算机结构中,进程是程序的基本执行实体,在当代面向线程设计的计算机结构中,进程是线程的容器;
  • 程序是指令、数据及其组织形式的描述,进程是程序的实体,我们自己在python文件中写了一些代码,这叫做程序,运行这个python文件的时候,这叫做进程;
  • 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed);
  • 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元;
2.什么是并发

在某个时间段内,两件或两件以上的事件轮流交替使用某一资源,目的是提高效率;
并发是指一次处理多件事,而并行是指一次做多件事;

3multiprocess模块
实例1:对比多线程和多进程程序运行对CPU的使用情况
import multiprocessing
import threading
def worker():
    number = 0
    for i in range(10000000):
        number += 1
        print('循环次数:{} number:{}'.format(i+1,number ))
if __name__ == '__main__':
    for i in range(4):
        threading.Thread(target=worker, name='thread worker {}'.format(i)).start()
        # multiprocessing.Process(target=worker, name='process worker {}'.format(i)).start()

# 实例2:进程的一些对象方法

import multiprocessing
import threading
import time

def worker():
    number = 0
    for i in range(10000000):
        number += 1
        time.sleep(0.1)
        print(multiprocessing.current_process().name)  # 获取当前进程的名称
        print('循环次数:{} number:{}'.format(i+1,number ))
        
if __name__ == '__main__':
    for i in range(4):
        process = multiprocessing.Process(target=worker, name='process worker {}'.format(i))
        process.start()
        print(process.pid) # 获取进程的pid
        print(process.exitcode) # 获取退出状态码
        print(process.name)  # 获取进程名称
        time.sleep(30)
        print(process.terminate()) # 终止进程
  • Python中提供multiprocess模块实现多进程并发;

  • multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了ProcessQueuePipeLock等 组件;

  • 可以multiprocessing.Process对象来创建一个进程,该进程可以运行在Python程序内部编写的函数;

  • process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建,有start()run()join()的方法;

4.进程并发:concurrent模块

from concurrent.futures import ProcessPoolExecutor
import requests

def fetch_url(url):
    result = requests.get(url=url, )
    return result.text
if __name__ == '__main__':
    # 创建10个线程队列的线程池
    pool = ProcessPoolExecutor(10)
    # 获取任务返回对象
    a = pool.submit(fetch_url, 'http://www.baidu.com')
    # 取出返回的结果
    x = a.result()
    print(x)

# 示例2:也可以使用上下文管理
from concurrent.futures import ProcessPoolExecutor
import requests

def fetch_url(url):
    result = requests.get(url=url, )
    return result.text
if __name__ == '__main__':
    with ProcessPoolExecutor(max_workers=10) as pool:
        a = pool.submit(fetch_url, 'http://www.9xkd.com')
        print(a.result())
  • concurrent模块能够提供一个future的实例对象,实例对象提供了线程的执行器和进程的执行器;

  • submit():返回一个Future对象;

  • result():查看调用的返回结果;

  • done():如果任务成功执行或任务取消返回True;

  • cancel():取消任务;

  • running():如果任务正在执行返回True;

  • exception(): 获取执行抛出的异常;

5.守护进程实现(POSIX兼容)
  • 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期 性的执行某种任务或等待处理某些发生的事件;

  • 由于在linux中,每个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终 端,这个终端被称为这些进程的控制终端,当控制终端被关闭的时候,相应的进程都会自动关闭;

  • 但是守护进程却能突破这种限制,它脱离于终端并且在后台运行,并且它脱离终端的目的是为了避免进程在运 行的过程中的信息在任何终端中显示并且进程也不会被任何终端所产生的终端信息所打断,它从被执行的时候 开始运转,直到整个系统关闭才退出;

守护进程实现的步骤:

  • 父进程fork出子进程并exit退出;

  • 子进程调用setsid创建新会话;

  • 子进程调用系统函数chdir将根目录"/"成为子进程的工作目录;

  • 子进程调用系统函数umask将该进程的umask设置为0;

  • 子进程关闭从父进程继承的所有不需要的文件描述符;

对 os.fork( )的理解:

  • os.fork()返回两个值,一个是在当前父进程返回的,一个是在子进程中返回的;

  • 子进程返回的是0,父进程返回的是子进程的pid;

import os
pid = os.fork()
print(pid)
if pid == 0:
    print("我是子进程 pid={}, parent_pid={}".format(os.getpid(), os.getppid()))
else:
    print("我是父进程 pid={}, parent_pid={}".format(os.getpid(), os.getppid()))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值