python进程学习

前言

进程是操作系统的中执行的程序,操作系统以进程为单位分配存储系统,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程的辅助数据,操作系统管理所有进程的执行,为它们分配合理的资源。由于进程是一个独立的内存空间,所以他们之间必须通过进程间通信机制(IPC,Inter-Process Communication)来实现数据共享。
具体的共享方式有,管道、套接字、信号、共享内存等。

进程的概念

狭义的定义:进程是一段程序的执行过程
广义的定义:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基>本的执行单

  1. 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  2. 并发性:任何进程都可以同其他进程一起并发执行
  3. 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
  4. 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推 进
  5. 结构特征:进程由程序、数据和进程控制块三部分组成;
    多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果; 但是执行过程中,程序不能发生改变。

1. python中的多进程

python中的进程通过multiprocessing模块来实现

import os
import time
from random import randint
from multiprocessing import Process


def download_task(file):
    print("start download, this process pid:{}".format(os.getpid()))
    print("start download, this process parent pid:{}".format(os.getppid()))
    print("start download file:{}".format(file))
    time_to_download = randint(5, 10)
    time.sleep(time_to_download)
    print("{} download finished,cost time :{}".format(file, time_to_download))


def main():
    start = time.time()
    print("main current pid %d" % os.getpid())
    print("main parent pid %d" % os.getppid())
    args = ('tencent', 'ali')
    process_list = []
    # python中的多进程
    for i in args:
        p = Process(target=download_task, args=(i,))
        p.start()
        process_list.append(p)
    for j in process_list:
        j.join()
    end = time.time()
    print("total cost time %.2f" % (end - start))


if __name__ == '__main__':
    main()

2.进程池

Pool即进程池,可以设置进程的数量。

import os
import time
from random import randint
from multiprocessing import Pool


def download_task(name):
    print("current task parent pid:%d, child pid:%s" % (os.getppid(), os.getpid()))
    time_to_download = randint(5, 10)
    time.sleep(time_to_download)
    print("download_task file %s total cost time:%d" % (name, time_to_download))


if __name__ == '__main__':
    start = time.time()
    total_download_time = 0
    print("parent pid is:%d" % os.getpid())
    p = Pool(processes=2)
    for i in range(10):
        p.apply_async(download_task, args=(i,))
    print("wait for all process done")
    p.close()
    p.join()
    end = time.time()
    print("python pool total cost time %.2f, %d" % (end - start, total_download_time))

3.进程加锁

锁的作用是保证在同一时间内只运行一个进程

import time
import random
from multiprocessing import Process, Lock


def download_task(name):
    lock.acquire()
    download_time = random.randint(5, 10)
    time.sleep(download_time)
    print("download_task name:{}, download_time:{}".format(name, download_time))
    lock.release()


lock = Lock()
if __name__ == '__main__':
    start = time.time()
    process_list = []
    for i in range(10):
        p = Process(target=download_task, args=(i,))
        p.start()
        process_list.append(p)

    for j in process_list:
        j.join()
    end = time.time()
    print("python_lock total cost time :{}".format(end - start))

4.进程之间的通信方式

这里介绍两种常见的通信方式,管道,队列

1.Pipe管道


import os
import time
from random import randint
from multiprocessing import Process, Pipe


def download_task(conn, name):
    print("download_task current_pid:%d" % os.getpid())
    download_time = randint(5, 10)
    time.sleep(download_time)
    conn.send(['download' + str(name)])
    print("%s download_task finished download_time:%d" % (name, download_time))


if __name__ == '__main__':
    start = time.time()
    process_list = []

    parent_conn, child_conn = Pipe()
    for i in range(10):
        p = Process(target=download_task, args=(child_conn, i))
        p.start()
        process_list.append(p)
    for j in process_list:
        j.join()
    for k in range(10):
        print(parent_conn.recv())
    end = time.time()
    print("this python_pipe total cost time: %.2f" % (end - start))

2.Queue队列

import os
import time
from multiprocessing import Process, Queue


def f(name, que):
    print("start process current pid: %d" % os.getpid())
    time.sleep(1)
    que.put(['hello' + str(name)])


if __name__ == '__main__':
    process_list = []
    q = Queue()
    for i in range(10):
        p = Process(target=f, args=(i, q))
        p.start()
        process_list.append(p)
        print(q.get())

    for j in process_list:
        j.join()

5.进程之间共享内存

通过Array,Value,Maneger等来实现进程之间的内存共享

1. Array,Value


"""进程之间共享内存"""

import os
import time
from multiprocessing import Process, Value, Array


def download_task(n, a, name):
    time.sleep(1)
    n.value = name * name
    print("download_task name:{}".format(name))
    for k in range(len(a)):
        a[k] = -k  # 添加到列表中


if __name__ == '__main__':
    # 通过使用Value或者Array把数据存储在一个共享的内存表中
    # 'd'和'i'参数是num和arr用来设置类型,d表示一个整数类型,i表示一个带符号的整型。
    num = Value('i', 0)
    arr = Array('d', range(10))
    process_list = []
    for i in range(10):
        p = Process(target=download_task, args=(num, arr, i))
        p.start()
        process_list.append(p)

    for j in process_list:
        j.join()

    print("download_task value:{}".format(num.value))  # 返回最后一个子进程运行的值
    print("download_task arr:{}".format(arr[:]))

2. Manager

# 比共享内存灵活,但缓慢
# 支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array

import os
import time
from multiprocessing import Process, Manager


def download_task(dm, name):
    # print("download_task current pid:%d" % os.getpid())
    dm[name] = name * name
    # print("download_task dm:%s, name:%d" % (dm, name))


if __name__ == '__main__':
    manager = Manager()
    d = manager.dict()
    process_list = []
    for i in range(10):
        p = Process(target=download_task, args=(d, i))
        p.start()
        process_list.append(p)

    for j in process_list:
        j.join()
        print("download_task d:{}".format(d))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值