进程_7180进程启动-程序员宅基地

技术标签: python  多任务  多进程  python学到死  

进程

一.什么是多任务

现代的操作系统(Windows,Mac OS X,Linux,UNIX等)都支持“多任务”。
什么叫做多任务:操作系统同时运行多个任务

  • 单核CPU实现多任务原理:操作系统轮流让各个任务交替执行,QQ执行2us,切换到微信,再执行2us,再切换到陌陌,执行2us······。表面上是每个任务反复执行下去,但是CPU调度执行速度太快了,导致我们感觉就像所有任务都在同时执行一样。

  • 多核CPU实现多任务原理:真正的并行执行多任务只能在多核CPU上实现,但是由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。

并发:看上去一起执行,任务数多于CPU核心数
并行:真正一起执行,任务数小于等于CPU核心数

二、实现多任务的方式:

1.多进程模式(使用较多)
2.多线程模式(使用最多)
3.协程模式 (使用较少)
4.多进程+多线程模式 (容易出错)

生活中与很多场景是同时进行的,比如开车的时候手和脚是同时来控制车。还有一些歌手边唱歌边跳舞。
我们可以理解为我们的大脑控制着我们的身体进行不同的动作。大脑就是cpu,身体的所有支配动作用到的部位为我们的资源。
试想下如果我们的大脑只能控制一个动作完成后才能控制下一个动作,也就是说我们只能先唱完歌再去跳舞,这是不是很尴尬呢?

示例1 一般情况下执行唱歌、跳舞

from time import sleep 
def sing():
    for i in range(3):
        print('我正在唱歌。。。%d'%i)
        sleep(1)

def dance():
    for i in range(3):
        print('我正在跳舞。。。%d'%i)
        sleep(1)
if __name__ == '__main__':
    sing() # 先唱歌
    dance() # 再跳舞
'''
我正在唱歌。。。0
我正在唱歌。。。1
我正在唱歌。。。2
我正在跳舞。。。0
我正在跳舞。。。1
我正在跳舞。。。2'''

示例2 单线程执行函数

from time import sleep
# 单线程执行
def saySorry():
    print("亲爱的,圣诞节快乐!")
    sleep(1)

if __name__ == "__main__":
    for i in range(5):
        saySorry()
"""
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
"""

示例3 多线程执行函数

import threading
from time import sleep
# 多线程执行
def saySorry():
    print("亲爱的,圣诞节快乐!")
    sleep(1)

if __name__ == "__main__":
    for i in range(5):
        t = threading.Thread(target=saySorry)
        t.start()  # 启动线程,即让线程开始执行
"""
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
# 亲爱的,圣诞节快乐!
"""

示例4多线程执行唱歌、跳舞1

import threading
from time import sleep,ctime
# 多线程执行唱歌跳舞的多任务。
def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)
        sleep(1)

def dance():
    for i in range(3):
        print("正在跳舞...%d"%i)
        sleep(1)

if __name__ == '__main__':
    print('---开始---:%s'%ctime())

    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)

    t1.start()
    t2.start()

    sleep(5)  # 屏蔽此行代码,试试看,程序是否会立马结束?
    print('---结束---:%s'%ctime())

'''
---开始---:Tue May 25 11:26:19 2021
正在唱歌...0
正在跳舞...0
正在唱歌...1
正在跳舞...1
正在唱歌...2
正在跳舞...2
---结束---:Tue May 25 11:26:24 2021
'''

示例5多线程执行唱歌、跳舞2

import threading
from time import sleep,ctime
# 多线程执行唱歌跳舞的多任务。
def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)
        sleep(1)

def dance():
    for i in range(3):
        print("正在跳舞...%d"%i)
        sleep(1)

if __name__ == '__main__':
    print('---开始---:%s'%ctime())

    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)

    t1.start()
    t2.start()

    # sleep(5) # 屏蔽此行代码,试试看,程序是否会立马结束?
    print('---结束---:%s'%ctime())

'''---开始---:Tue May 25 11:19:25 2021
正在唱歌...0
正在跳舞...0---结束---:Tue May 25 11:19:25 2021

正在唱歌...1
正在跳舞...1
正在唱歌...2
正在跳舞...2'''

三、什么是进程

1.什么是进程?

对于操作系统而言,一个任务就是一个进程,一个应用就是一个进程。
程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念,而进程是程序在处理机上的一次执行过程,它是一个动态的概念。
进程是系统中程序执行和资源分配的基本单位,每个进程都有自己的数据段、代码段、和堆栈段。
进程是一个具有一定独立功能的程序,一个实体,每一个进程都有它自己的地址空间。

2.进程的状态

进程执行时的间断性,决定了进程可能具有多种状态,事实上,运行中的进程具有以下三种基本状态。
(1)就绪状态(Ready)
(2)运行状态(Running)
(3)阻塞状态(Blocked)

3.单任务现象

# 单任务现象
from time import sleep

def run():
    while True:
        print("haiyan is my wife")
        sleep(2)

if __name__ == "__main__":
    while True:
        print("yangyu is a good man")
        sleep(1)

    run()    # 执行不了.因为上面的循环没有结束。
'''
执行结果:不停打印
yangyu is a good man
yangyu is a good man
yangyu is a good man
yangyu is a good man
yangyu is a good man
yangyu is a good man
yangyu is a good man
yangyu is a good man
...
'''

4.启动进程实现多任务

# 启动进程实现多任务
"""
multiprocessing 库
跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象
"""
from multiprocessing import Process
import os
from time import sleep


# 子进程需要执行的代码
def run(str1):
    while True:
        # os.getpid()获取当前进程的id号
        # os.getppid()获取当前父进程的id号
        print("yangyu is a %s man--%s--%s" % (str1, os.getpid(), os.getppid()))
        sleep(1.2)


if __name__ == "__main__":
    print("主(父)进程启动-%s" % (os.getpid()))
    # 创建子进程
    # target说明进程执行的任务
    p = Process(target=run, args=("nice",))
    # 启动进程
    p.start()

    while True:
        print("yangyu is a good man")
        sleep(1)
'''
主(父)进程启动-2372
yangyu is a good man
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a nice man--5664--2372
yangyu is a good man
yangyu is a good man
yangyu is a nice man--5664--2372'''

5.父子进程的先后顺序

# 父子进程的先后顺序
from multiprocessing import Process
from time import sleep

def run(str1,str2):
    print("子进程启动+%s"%str1)
    sleep(3)
    print("子进程结束+%s"%str2)

if __name__ == "__main__":
    print("父进程启动")

    p = Process(target=run, args=("start","end"))
    p.start()

    # 父进程的结束不能影响子进程,让父进程等待子进程的结束再执行父进程
    p.join()
    print("父进程结束")
'''
父进程启动
子进程启动+start
子进程结束+end
父进程结束
'''

6.多个进程不能共享全局变量

# 多个进程不能共享全局变量
# 在子进程中修改全局变量对父进程中的全局变量没有影响
# 在创建子进程时对全局变量做了一个备份,父进程中的子进程中的num是完全不同的两个变量
from multiprocessing import Process
num = 100
def run():
    print("子进程开始")
    global num  # num = 100
    num += 1
    print(num)
    print("子进程结束")

if __name__ == "__main__":
    print("父进程开始")
    p = Process(target=run)
    p.start()
    p.join()
    print("父进程结束--%d"%num)
'''
父进程开始
子进程开始
101
子进程结束
父进程结束--100
'''

7.启动多个子进程

# 启动多个子进程
from multiprocessing import Pool
import os,time
def run(name):
    print("子进程%d启动--%s" % (name, os.getpid()))
    start = time.time()
    time.sleep(3)
    end = time.time()
    print("子进程%d结束--%s--耗时%.2f" % (name, os.getpid(), end-start))

if __name__ == "__main__":
    t1 = time.time()
    print("父进程启动")
    # 创建多个进程
    # 进程池
    # 表示可以同时执行的进程数量
    # Pool默认大小是cpu核心线程数,我的笔记本电脑是2核4线程(这里的线程就同时执行的进程),Pool()默认为4,默认同时执行4进程,总耗时为18.2s;改为2,总耗时为32.5s;改为8,总耗时14.1s;改为20,总耗时20.35s。所有一般就用核心数*线程数(2*4=8),执行速度最快。
    pp = Pool(8)
    for i in range(20):
        # 创建进程,放入进程池同意管理
        pp.apply_async(run, args=(i,))
    # 在调用join之前必须先调用close,调用close之后就不能再继续添加新的进程了
    pp.close()
    # 进程池对象调用join,会等待进程池中所有的子进程结束完毕再去执行父进程
    pp.join()
    print("父进程结束,总耗时为%s"%(time.time()-t1))
'''
父进程启动
子进程0启动--9048
子进程1启动--3648
子进程2启动--7180
子进程3启动--7888
子进程4启动--8228
子进程5启动--8664
子进程6启动--8688
子进程7启动--9432
子进程0结束--9048--耗时3.01
子进程8启动--9048
子进程1结束--3648--耗时3.01
子进程9启动--3648
子进程2结束--7180--耗时3.01
子进程10启动--7180
子进程3结束--7888--耗时3.01
子进程11启动--7888
子进程4结束--8228--耗时3.01
子进程12启动--8228
子进程5结束--8664--耗时3.01
子进程13启动--8664
子进程6结束--8688--耗时3.01
子进程14启动--8688
子进程7结束--9432--耗时3.01
子进程15启动--9432
子进程8结束--9048--耗时3.07
子进程16启动--9048
子进程9结束--3648--耗时3.01
子进程17启动--3648
子进程10结束--7180--耗时3.01
子进程18启动--7180
子进程11结束--7888--耗时3.01
子进程19启动--7888
子进程12结束--8228--耗时3.01
子进程13结束--8664--耗时3.01
子进程14结束--8688--耗时3.01
子进程15结束--9432--耗时3.01
子进程16结束--9048--耗时3.01
子进程17结束--3648--耗时3.01
子进程18结束--7180--耗时3.04
子进程19结束--7888--耗时3.01
父进程结束,总耗时为14.196025133132935
'''

8.多进程文件拷贝

1.普通文件拷贝

# 实现文件的拷贝
import os, time
def copyFile(rPath, wPath):
    fr = open(rPath, "rb")
    fw = open(wPath, "wb")
    context = fr.read()
    fw.write(context)
    fr.close()
    fw.close()

path = r"F:\PycharmProjects\Project\进程\file1\1905热门电影图片"
toPath = r"F:\PycharmProjects\Project\进程\file2"

# 读取path下的所有文件
fileList = os.listdir(path)

# 启动for循环去处理每个文件
start = time.time()
for fileName in fileList:
    copyFile(os.path.join(path,fileName), os.path.join(toPath, fileName))
end = time.time()
print("总耗时:%0.2f" % (end-start))  # 总耗时:14.68

2.多进程文件拷贝

import os, time
from multiprocessing import Pool
# 实现文件的拷贝
def copyFile(rPath, wPath):
    fr = open(rPath, "rb")
    fw = open(wPath, "wb")
    context = fr.read()
    fw.write(context)
    fr.close()
    fw.close()

path = r"F:\PycharmProjects\Project\进程\file1\1905热门电影图片"
toPath = r"F:\PycharmProjects\Project\进程\file2"

if __name__ == "__main__":
    # 读取path下的所有文件
    fileList = os.listdir(path)
    start = time.time()
    pp = Pool(4)
    for fileName in fileList:
        pp.apply_async(copyFile, args=(os.path.join(path, fileName), os.path.join(toPath, fileName)))
    pp.close()
    pp.join()
    end = time.time()
    print("总耗时:%0.2f" % (end - start))  # 总耗时:11.40

9.封装进程对象

1.创建yangyuProcess.py文件

from multiprocessing import Process
import os, time

class YangyuProcess(Process):
    def __init__(self, name):
        Process.__init__(self)
        self.name = name

    def run(self):
        print("子进程(%s-%s)启动" % (self.name, os.getpid()))

        # 子进程的功能
        time.sleep(3)

        print("子进程(%s-%s)结束" % (self.name, os.getpid()))

2.from yangyuProcess import YangyuProcess

from yangyuProcess import YangyuProcess

if __name__ == "__main__":
    print("父进程启动")
    # 创建子进程
    p = YangyuProcess("test")
    # 自动调用p进程对象的run方法
    p.start()
    p.join()
    print("父进程结束")
'''
打印结果:
父进程启动
子进程(test-3476)启动
子进程(test-3476)结束
父进程结束
'''
"""
这样写的好处:子进程的方法不用和父进程的方法写在一起,让主程序结构更清晰。
"""

10.进程间的通信

1.示例1

from multiprocessing import Process, Queue
import os,time

def write(q):
    print("启动写子进程%s"%(os.getpid()))
    for chr in ["A","B","C","D"]:
        q.put(chr)
        time.sleep(1)
    print("结束写子进程%s"%(os.getpid()))

def read(q):
    print("启动读子进程%s" % (os.getpid()))
    while True:
        value = q.get(True)
        print("value=" + value)
    print("结束读子进程%s" % (os.getpid()))


if __name__ == "__main__":
    # 父进程创建队列,并传给子进程
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))

    pw.start()
    pr.start()

    pw.join()
    pr.terminate()  # pr进程里是个死循环,无法等待其结束,只能强制结束

    print("父进程结束")

'''
启动写子进程7752
启动读子进程7264
value=A
value=B
value=C
value=D
结束写子进程7752
父进程结束'''

2.示例2

from multiprocessing import Process, Queue
import os,time

def write(q):
    print("启动写子进程%s"%(os.getpid()))
    for chr in ["A","B","C","D"]:
        q.put(chr)
        print(chr)
    print("结束写子进程%s"%(os.getpid()))

def read(q):
    print("启动读子进程%s" % (os.getpid()))
    while not q.empty():
        value = q.get(True)
        print("value=" + value)
        time.sleep(1)
    print("结束读子进程%s" % (os.getpid()))


if __name__ == "__main__":
    print("父进程开始")
    # 父进程创建队列,并传给子进程
    q = Queue(4)
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))

    pw.start()
    pr.start()
    pw.join()
    pr.join()
    print("父进程结束")

'''
父进程开始
启动写子进程8228
A
B
C
D
结束写子进程8228
启动读子进程7472
value=A
value=B
value=C
value=D
结束读子进程7472
父进程结束
'''
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yangyusir/article/details/117255492

智能推荐

51单片机的中断系统_51单片机中断篇-程序员宅基地

文章浏览阅读3.3k次,点赞7次,收藏39次。CPU 执行现行程序的过程中,出现某些急需处理的异常情况或特殊请求,CPU暂时中止现行程序,而转去对异常情况或特殊请求进行处理,处理完毕后再返回现行程序断点处,继续执行原程序。void 函数名(void) interrupt n using m {中断函数内容 //尽量精简 }编译器会把该函数转化为中断函数,表示中断源编号为n,中断源对应一个中断入口地址,而中断入口地址的内容为跳转指令,转入本函数。using m用于指定本函数内部使用的工作寄存器组,m取值为0~3。该修饰符可省略,由编译器自动分配。_51单片机中断篇

oracle项目经验求职,网络工程师简历中的项目经验怎么写-程序员宅基地

文章浏览阅读396次。项目经验(案例一)项目时间:2009-10 - 2009-12项目名称:中驰别克信息化管理整改完善项目描述:项目介绍一,建立中驰别克硬件档案(PC,服务器,网络设备,办公设备等)二,建立中驰别克软件档案(每台PC安装的软件,财务,HR,OA,专用系统等)三,能过建立的档案对中驰别克信息化办公环境优化(合理使用ADSL宽带资源,对域进行调整,对文件服务器进行优化,对共享打印机进行调整)四,优化完成后..._网络工程师项目经历

LVS四层负载均衡集群-程序员宅基地

文章浏览阅读1k次,点赞31次,收藏30次。LVS:Linux Virtual Server,负载调度器,内核集成, 阿里的四层SLB(Server Load Balance)是基于LVS+keepalived实现。NATTUNDR优点端口转换WAN性能最好缺点性能瓶颈服务器支持隧道模式不支持跨网段真实服务器要求anyTunneling支持网络private(私网)LAN/WAN(私网/公网)LAN(私网)真实服务器数量High (100)High (100)真实服务器网关lvs内网地址。

「技术综述」一文道尽传统图像降噪方法_噪声很大的图片可以降噪吗-程序员宅基地

文章浏览阅读899次。https://www.toutiao.com/a6713171323893318151/作者 | 黄小邪/言有三编辑 | 黄小邪/言有三图像预处理算法的好坏直接关系到后续图像处理的效果,如图像分割、目标识别、边缘提取等,为了获取高质量的数字图像,很多时候都需要对图像进行降噪处理,尽可能的保持原始信息完整性(即主要特征)的同时,又能够去除信号中无用的信息。并且,降噪还引出了一..._噪声很大的图片可以降噪吗

Effective Java 【对于所有对象都通用的方法】第13条 谨慎地覆盖clone_为继承设计类有两种选择,但无论选择其中的-程序员宅基地

文章浏览阅读152次。目录谨慎地覆盖cloneCloneable接口并没有包含任何方法,那么它到底有什么作用呢?Object类中的clone()方法如何重写好一个clone()方法1.对于数组类型我可以采用clone()方法的递归2.如果对象是非数组,建议提供拷贝构造器(copy constructor)或者拷贝工厂(copy factory)3.如果为线程安全的类重写clone()方法4.如果为需要被继承的类重写clone()方法总结谨慎地覆盖cloneCloneable接口地目的是作为对象的一个mixin接口(详见第20_为继承设计类有两种选择,但无论选择其中的

毕业设计 基于协同过滤的电影推荐系统-程序员宅基地

文章浏览阅读958次,点赞21次,收藏24次。今天学长向大家分享一个毕业设计项目基于协同过滤的电影推荐系统项目运行效果:项目获取:https://gitee.com/assistant-a/project-sharing21世纪是信息化时代,随着信息技术和网络技术的发展,信息化已经渗透到人们日常生活的各个方面,人们可以随时随地浏览到海量信息,但是这些大量信息千差万别,需要费事费力的筛选、甄别自己喜欢或者感兴趣的数据。对网络电影服务来说,需要用到优秀的协同过滤推荐功能去辅助整个系统。系统基于Python技术,使用UML建模,采用Django框架组合进行设

随便推点

你想要的10G SFP+光模块大全都在这里-程序员宅基地

文章浏览阅读614次。10G SFP+光模块被广泛应用于10G以太网中,在下一代移动网络、固定接入网、城域网、以及数据中心等领域非常常见。下面易天光通信(ETU-LINK)就为大家一一盘点下10G SFP+光模块都有哪些吧。一、10G SFP+双纤光模块10G SFP+双纤光模块是一种常规的光模块,有两个LC光纤接口,传输距离最远可达100公里,常用的10G SFP+双纤光模块有10G SFP+ SR、10G SFP+ LR,其中10G SFP+ SR的传输距离为300米,10G SFP+ LR的传输距离为10公里。_10g sfp+

计算机毕业设计Node.js+Vue基于Web美食网站设计(程序+源码+LW+部署)_基于vue美食网站源码-程序员宅基地

文章浏览阅读239次。该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流项目运行环境配置:项目技术:Express框架 + Node.js+ Vue 等等组成,B/S模式 +Vscode管理+前后端分离等等。环境需要1.运行环境:最好是Nodejs最新版,我们在这个版本上开发的。其他版本理论上也可以。2.开发环境:Vscode或HbuilderX都可以。推荐HbuilderX;3.mysql环境:建议是用5.7版本均可4.硬件环境:windows 7/8/10 1G内存以上;_基于vue美食网站源码

oldwain随便写@hexun-程序员宅基地

文章浏览阅读62次。oldwain随便写@hexun链接:http://oldwain.blog.hexun.com/ ...

渗透测试-SQL注入-SQLMap工具_sqlmap拖库-程序员宅基地

文章浏览阅读843次,点赞16次,收藏22次。用这个工具扫描其它网站时,要注意法律问题,同时也比较慢,所以我们以之前写的登录页面为例子扫描。_sqlmap拖库

origin三图合一_神教程:Origin也能玩转图片拼接组合排版-程序员宅基地

文章浏览阅读1.5w次,点赞5次,收藏38次。Origin也能玩转图片的拼接组合排版谭编(华南师范大学学报编辑部,广州 510631)通常,我们利用Origin软件能非常快捷地绘制出一张单独的绘图。但是,我们在论文的撰写过程中,经常需要将多种科学实验图片(电镜图、示意图、曲线图等)组合在一张图片中。大多数人都是采用PPT、Adobe Illustrator、CorelDraw等软件对多种不同类型的图进行拼接的。那么,利用Origin软件能否实..._origin怎么把三个图做到一张图上

51单片机智能电风扇控制系统proteus仿真设计( 仿真+程序+原理图+报告+讲解视频)_电风扇模拟控制系统设计-程序员宅基地

文章浏览阅读4.2k次,点赞4次,收藏51次。51单片机智能电风扇控制系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0042。_电风扇模拟控制系统设计