进程_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

智能推荐

SQuirreL SQL Client 使用记录-程序员宅基地

文章浏览阅读76次。如果您的工作要求您在一天之中连接许多不同的数据库 (oracle、DB2、mysql、postgresql、Sql Server等等),或者你经常需要在多个不同种类的数据库之间进行数导入导出。那么SQuirreL SQL Client 将会是比较理想的数据库客户端链接工具。简单介绍: SQuirrel SQL Client是一个用Java写的数据库客户端,用JDBC统一数..._squirrel运行日志

【每日算法Day 99】你们可能不知道只用20万赢到578万是什么概念-程序员宅基地

文章浏览阅读1.3k次。你们可能不知道只用 20 万赢到 578 万是什么概念。 我们一般只会用两个字来形容这种人:赌怪! 我经常说一句话,当年陈刀仔他能用 20 块赢到 3700 万,我 LBW 用 20 万赢到 500 万不是问题。 埋伏他一手,这个牌不能抢,这个牌不用抢,他死定了。 反手给一个超级加倍,闷声发大财。他也超级加倍?但是不用怕,他的牌赢不了我。 五六七八九十,两个炸,很牛逼这个牌,如果把..._你们可能不知道只用20万赢到578万是什么概念

使用 LINQPad 将linq转换为 lambda表达式 或者 SQL语句_net lambda表达式转sql语句类库-程序员宅基地

文章浏览阅读3.4k次。一、LINQPad有多用途分析功能,即显示结果的多种选择 1、默认结果视图由语句返回的对象和文本的简单图形 2、Lambda视图LINQ表达式转换为可用的Lambda表达式 3、SQL视图LINQ表达式转换为可用的SQL 4、IL视图针对代码生成的微软中间语言 二、LINQPad 执行linq后的界面如图_net lambda表达式转sql语句类库

Swustoj题目征集计划-程序员宅基地

文章浏览阅读85次。SWUST OJ题目征集计划鉴于SWUST OJ长时间没有新题添加,题目数量和类型有限,同时也为加强同学们之间的算法交流,享受互相出题AC的乐趣,提高算法水平,现在启动题目征集计划啦~当你遇到或想到一道好的题目时,是否很想和他人分享?如果你有好的题目,赶快投递过来吧,让大家一起嗨嗨嗨起来!!!以下是详细说明:一、关于题目题目部分,出题人需要提供以..._建立长度为n的单链表,n>0,然后将其数据元素逆置

Redis——Linux下安装以及命令操作_redis add命令-程序员宅基地

文章浏览阅读553次。Redis(Remote Dictionary Server ),即远程字典服务是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。是一款高性能的NOSQL系列的非关系型数据库_redis add命令

MSP430用按键中断控制定时器产生持续 1s 的周期信号_msp430g2553设置一个1秒的定时器-程序员宅基地

文章浏览阅读5.1k次。//////////////////////////////////////////////////////////////////////////////////////////////////////// 2012 年吉林省大学生电子设计大赛 C题> ----(声源部分)// 要求: 有信号产生电路, 放大电路, 声音频率 800Hz 左右, 按一次键响声持续 1 秒.//_msp430g2553设置一个1秒的定时器

随便推点

windows获取CPU温度_c++如何监控cpu温度-程序员宅基地

文章浏览阅读5.6k次,点赞2次,收藏16次。CPU温度,电脑温度,windows硬件温度_c++如何监控cpu温度

「进击 Redis」二十六、你竟然还不知道 hash slot-程序员宅基地

文章浏览阅读242次。前言Redis 系列第二十七篇,也是Cluster 集群模式第二篇。 上篇我们已经通过画图与对比的方式将Cluster 虚拟槽寻址思路、取余hash和一致性hash寻址的原理弄清楚了,还有不熟悉的好哥哥可以看你竟然还不知道 hash slot 这篇了解一下。这一篇的话主要是对Cluster 集群的搭建与使用,上一篇又说到分成两篇的,想想篇幅还是不要那么长,于是乎就有了一篇。这一篇的话基本上都是一些实践性的内容,好哥哥们还是一样不要偷懒哦。有杠精好哥哥会说了,怎么哨兵模式的搭建你怎么不弄?有这么杠的好哥哥_hash slot

AI绘画Midjourney的咒语关键词汇总结_ai咒语词典-程序员宅基地

文章浏览阅读7.6k次,点赞6次,收藏37次。一个爱冒险的8岁可爱男孩,他喜欢探索和了解世界,在森林里,皮克斯动画风格,C4D,OC渲染器半身像镜头,黏土雕塑材质,电影照明,高质量,多细节,高清。_ai咒语词典

Listview使用-程序员宅基地

文章浏览阅读63次。ListView控件比前面几种控件要复杂一些,通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本。ListView控件是由ColumnHeader和ListItem对象所组成的,其中ColumnHeader对象的个数决定了控件的列数,而ListItem对象的个数则决定了控件的行数。(图7)  ColumnHeader对象是ListView控件中包含标头文字的项目。利用Colum..._tooltip1和listview中columnheader使用

远程管理服务器的时候反应特别慢_远程资源管理器速度慢-程序员宅基地

文章浏览阅读3.3k次。问题:远程管理服务器的时候反应特别慢,在命令行敲命令的时候很长时间才在终端显示出来怀疑原因:1、查看远程服务器CPU负载情况、内存使用情况、磁盘IO等系统资源使用情况,可以使用sar、uptime、top、iostat、vmstat等2、查看网络是否稳定,使用 ping 查看是否丢包严重..._远程资源管理器速度慢

C语言实现三次样条插值_typedef struct tagpoint // 插值点的结构体成员有x, y { double-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏13次。#include <stdio.h># define MAX_N 20 // 定义(x_i,y_i)的最大的维数 typedef struct tagPOINT // 点的结构 { double x; double y;} POINT; int main ( ) { int n; int i, k; POINT points[MAX_N + 1]; double h[MAX_N + 1], b[MAX_N + 1], c[_typedef struct tagpoint // 插值点的结构体成员有x, y { double x; double y; }

推荐文章

热门文章

相关标签