前言

之前程序执⾏都是⼀条腿⾛路,甚⾄是⽤⼀杆枪来打天下。

通过系统编程的学习,会让⼤家有“多条腿”⼀起⾛路,就好⽐有了⼀把机关枪。

此篇为深入理解进程第一篇,下面开始今天的说明~~~

多任务的引入

现实生活中

有很多的场景中的事情是同时进⾏的,⽐如开⻋的时候⼿和脚共同来驾驶汽⻋,再⽐如唱歌跳舞也是同时进⾏的;
如下视频是:迈克杰克逊的⼀段视频:

http://v.youku.com/v_show/id_XMzE5NjEzNjA0.html

试想,如果把唱歌和跳舞这2件事情分开依次完成的话,估计就没有那么好的效果了(想⼀下场景:先唱歌,然后在跳舞,O(∩_∩)O哈哈~)

程序中

如下程序,来模拟“唱歌跳舞”这件事情

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()#跳舞

运行结果如下:

!!!注意:

  • 很显然刚刚的程序并没有完成唱歌和跳舞同时进⾏的要求 
  • 如果想要实现“唱歌跳舞”同时进⾏,那么就需要⼀个新的⽅法,叫做:多任务

多任务的概念

什么叫“多任务”呢?简单地说,就是操作系统可以同时运⾏多个任务。打个⽐⽅,你⼀边在⽤浏览器上⽹,⼀边在听MP3,⼀边在⽤Word赶作业,这就 是多任务,⾄少同时有3个任务正在运⾏。还有很多任务悄悄地在后台同时运⾏着,只是桌⾯上没有显示⽽已。

现在,多核CPU已经⾮常普及了,但是,即使过去的单核CPU,也可以执⾏多任务。由于CPU执⾏代码都是顺序执⾏的,那么,单核CPU是怎么执⾏多任务的呢?
答案就是操作系统轮流让各个任务交替执⾏,任务1执⾏0.01秒,切换到任务2,任务2执⾏0.01秒,再切换到任务3,执⾏0.01秒……这样反复执⾏下去。 表⾯上看,每个任务都是交替执⾏的,但是,由于CPU的执⾏速度实在是太快了,我们感觉就像所有任务都在同时执⾏⼀样。

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

进程的创建-fork

1. 进程 VS 程序

编写完毕的代码,在没有运⾏的时候,称之为程序
正在运⾏着的代码,就成为进程
进程,除了包含代码以外,还有需要运⾏的环境等,所以和程序是有区别的。

2. fork( )

Python的os模块封装了常⻅的系统调⽤,其中就包括fork,可以在Python程 序中轻松创建⼦进程:

import os

# 注意:fork函数,只在Unix/Linux/Mac上运行,windows不可以
pid = os.fork() if pid == 0:
print('哈哈1')
else:
print('哈哈2')

运行结果:

说明:

  • 程序执⾏到os.fork()时,操作系统会创建⼀个新的进程(⼦进程),然后复制⽗进程的所有信息到⼦进程中
  • 然后⽗进程和⼦进程都会从fork()函数中得到⼀个返回值,在⼦进程中这 个值⼀定是0,⽽⽗进程中是⼦进程的id号

在Unix/Linux操作系统中,提供了⼀个fork()系统函数,它⾮常特殊。
普通的函数调⽤,调⽤⼀次,返回⼀次,但是fork()调⽤⼀次,返回两次,因 为操作系统⾃动把当前进程(称为⽗进程)复制了⼀份(称为⼦进程),然 后,分别在⽗进程和⼦进程内返回。
⼦进程永远返回0,⽽⽗进程返回⼦进程的ID。
这样做的理由是,⼀个⽗进程可以fork出很多⼦进程,所以,⽗进程要记下 每个⼦进程的ID,⽽⼦进程只需要调⽤getppid()就可以拿到⽗进程的ID。

3. getpid()、getppid()

import os

rpid = os.fork()
if rpid<0:
print("fork调用失败。")
elif rpid == 0:
print("我是子进程(%s),我的父进程是(%s)"%(os.getpid(),os.getppid()))
x+=1
else:
print("我是父进程(%s),我的子进程是(%s)"%(os.getpid(),rpid)) print("父子进程都可以执行这里的代码")

运⾏结果:

多进程修改全局变量

import os
import time num = 0 #注意:fork函数,只在Unix/Linux/Mac上运行,windows不可以
pid = os.fork() if pid == 0:
num+=1
print("哈哈1---num=%d"%num) else:
time.sleep(1)
num+=1
print("哈哈2---num=%d"%num)

运行结果:

总结:

多进程中,每个进程中所有数据(包括全局变量)都各有拥有⼀份,互不影响

多次fork问题

如果在⼀个程序,有2次的fork函数调⽤,是否就会有3个进程呢?

import os
import time # 注意,fork函数,只在Unix/Linux/Mac上运行,windows不可以
pid = os.fork()
if pid == 0:
print('哈哈1')
else:
print('哈哈2') pid = os.fork()
if pid == 0:
print('哈哈3')
else:
print('哈哈4') time.sleep(1)

运行结果:

说明:

⽗⼦进程的执⾏顺序

⽗进程、⼦进程执⾏顺序没有规律,完全取决于操作系统的调度算法

【python进阶】深入理解系统进程1的更多相关文章

  1. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

  2. python 变量进阶(理解)

    变量进阶(理解) 目标 变量的引用 可变和不可变类型 局部变量和全局变量 01. 变量的引用 变量 和 数据 都是保存在 内存 中的 在 Python 中 函数 的 参数传递 以及 返回值 都是靠 引 ...

  3. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  4. Python进阶:函数式编程实例(附代码)

    Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...

  5. Python进阶 - 对象,名字以及绑定

    Python进阶 - 对象,名字以及绑定 1.一切皆对象 Python哲学: Python中一切皆对象 1.1 数据模型-对象,值以及类型 对象是Python对数据的抽象.Python程序中所有的数据 ...

  6. Python进阶 - 命名空间与作用域

    Python进阶 - 命名空间与作用域 写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的绑定相关性很大,可以结合另一篇介绍Python名字.对象及其绑定的文章. 1. 命名空 ...

  7. 【python进阶】详解元类及其应用2

    前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...

  8. Python进阶:如何将字符串常量转化为变量?

    前几天,我们Python猫交流学习群 里的 M 同学提了个问题.这个问题挺有意思,经初次讨论,我们认为它无解. 然而,我认为它很有价值,应该继续思考怎么解决,所以就在私密的知识星球上记录了下来. 万万 ...

  9. Python进阶:全面解读高级特性之切片!

    导读:切片系列文章连续写了三篇,本文是对它们做的汇总.为什么要把序列文章合并呢?在此说明一下,本文绝不是简单地将它们做了合并,主要是修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔 ...

  10. Python进阶:迭代器与迭代器切片

    2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇.合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章节衔接做了大量改动.原系列的单篇就不删除了,毕竟也是 ...

随机推荐

  1. Android进阶(五)在Eclipse中关联Gson源码

    1)获得相应的jar包gson-2.2.4-sources.jar与gson-2.2.4-javadoc.jar. 2)在libs目录下新建src包和docs包,将相应jar包放入相应文件夹内. 3) ...

  2. 实战项目:通讯录&nbsp;UI—第十一天

     1.推出视图的两种方式:  1.通过导航控制器push到下一个界面,使用pop返回到上一个界面 2.通过模态的形式推出视图,不需要依赖于导航控制器,通过使用present到下一个界面,通过dismi ...

  3. 海量数据挖掘MMDS week2: 频繁项集挖掘 Apriori算法的改进:基于hash的方法

    http://blog.csdn.net/pipisorry/article/details/48901217 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  4. (四十七)Quartz2D引擎初步

    Quartz2D是跨平台的,同时支持iOS与Mac. 支持圆型裁剪,可以实现圆形头像等功能,也支持手势解锁.折线图等的制作. 对于复杂的UI界面,还可以通过Quartz2D将控件内部的结构画出来,可用 ...

  5. javascript语法之for-in语句

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Java之美[从菜鸟到高手演变]之设计模式四

    在阅读过程中有任何问题,请及时联系:egg. 邮箱:xtfggef@gmail.com 微博:http://weibo.com/xtfggef 转载请说明出处:http://blog.csdn.net ...

  7. AngularJS进阶(一)深入理解ANGULARUI路由_UI-ROUTER

    深入理解ANGULARUI路由_UI-ROUTER 最近在用 ionic写个webapp 看到几个demo中路由有好几种,搞的有点晕,查下资料研究下,做个笔记,其中大部分为摘抄别人的,做个说明免得被人 ...

  8. 【Visual C++】游戏编程学习笔记之六:多背景循环动画

    本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44264153 作者:ZeeCod ...

  9. ExtJS:GridPanel之renderer:function()和itemdblclick : function()方法参数详解

    要使用GridPanel,首先要定义Store,而在创建Store的时候必须要有Model,因此我们首先来定义Model: Ext.define("Gpsdata", { exte ...

  10. C语言实现牛顿迭代法解方程

    利用迭代算法解决问题,需要做好以下三个方面的工作: 一.确定迭代变量 在可以用迭代算法解决的问题中,我们可以确定至少存在一个可直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量. 二.建立迭 ...